Le protocole Codable a été introduit dans Swift pour simplifier le processus de sérialisation et de désérialisation des données, telles que JSON ou Property List. Auparavant, il était nécessaire de mettre en œuvre manuellement le parsing, ce qui était laborieux, sujet à des erreurs et peu lisible. L'automatisation de ce processus a permis de développer un code plus sûr et plus concis.
Problème : Le problème est que lors de l'application automatique de Codable, toutes les propriétés doivent également être Codable, et toute violation de cette chaîne nécessite la mise en œuvre explicite des méthodes de décodage et d'encodage. En outre, il existe des particularités lors de la manipulation de structures, de classes avec héritage, ainsi que lors de l'appariemment de clés personnalisées.
Solution : La solution consiste à utiliser Codable pour des modèles simples, à surveiller strictement les propriétés devant être sérialisées et, en cas de modèles complexes, à mettre en œuvre les méthodes encode(to:) et init(from:), ainsi qu'à utiliser CodingKeys pour apparier les clés.
Exemple de code :
struct User: Codable { let id: Int let name: String let email: String? enum CodingKeys: String, CodingKey { case id case name = "full_name" case email = "contact_email" } }
Caractéristiques clés :
Un classe avec héritage et des propriétés uniques de l'enfant peut-elle être correctement sérialisée automatiquement avec Codable ?
Non, pour les classes avec héritage, Swift exige une mise en œuvre manuelle de encode(to:) et init(from:) dans les sous-classes, sinon les propriétés du parent et de l'enfant ne seront pas sérialisées correctement. Exemple :
class Animal: Codable { let species: String } class Dog: Animal { let breed: String enum CodingKeys: String, CodingKey { case breed } required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) breed = try container.decode(String.self, forKey: .breed) try super.init(from: decoder) } override func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(breed, forKey: .breed) try super.encode(to: encoder) } }
Que se passe-t-il si une propriété dans une structure est marquée comme private, tout en utilisant Codable automatiquement ?
Si la propriété est privée et n'est pas déclarée comme var/let avec des CodingKeys explicites, elle ne sera ni sérialisée ni désérialisée. Par conséquent, pour les propriétés privées, il est essentiel de déclarer CodingKeys et de les inclure dans l'énumération si nécessaire.
Est-il possible d'implémenter Codable uniquement pour le décodage (uniquement lecture) ?
Oui, il suffit d'implémenter uniquement init(from:) et de se conformer au protocole Decodable au lieu de Codable.
struct ReadOnlyModel: Decodable { let id: Int }
** Cas négatif
Un développeur a ajouté une propriété calculée dans le modèle sans implémenter de méthodes encode et decode personnalisées, espérant un traitement automatique de Codable.
Avantages :
Inconvénients :
** Cas positif
Un développeur implémente des CodingKeys personnalisés et des méthodes encode/decode personnalisées pour des cas complexes où les propriétés ne correspondent pas aux clés, où il y a des champs calculés et de l'héritage est appliqué.
Avantages :
Inconvénients :