El protocolo Codable se introdujo en Swift para simplificar el proceso de serialización y deserialización de datos, como JSON o listas de propiedades. Anteriormente, era necesario implementar el análisis manualmente, lo que era laborioso, propenso a errores y difícil de leer. La automatización de este proceso permitió desarrollar un código más seguro y conciso.
El problema radica en que al aplicar Codable automáticamente, todas las propiedades también deben ser Codable, y cualquier violación de esta cadena requiere una implementación explícita de los métodos de decodificación y codificación. Además, hay particularidades al trabajar con estructuras, clases con herencia, así como al realizar mapeo personalizado de claves.
La solución consiste en usar Codable para modelos simples, prestar atención a qué propiedades deben serializarse, y en el caso de modelos complejos, implementar los métodos encode(to:) e init(from:), así como utilizar CodingKeys para el mapeo de claves.
Ejemplo de código:
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" } }
Características clave:
¿Puede una clase con herencia y propiedades únicas de la subclase ser serializada correctamente usando Codable automáticamente?
No, para clases con herencia, Swift requiere que se implementen manualmente encode(to:) e init(from:) en las subclases, de lo contrario, las propiedades del padre y de la subclase no se serializan correctamente. Ejemplo:
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) } }
¿Qué ocurrirá si una propiedad en una estructura está marcada como privada, mientras se utiliza Codable automático?
Si la propiedad es privada y no está declarada como var/let con CodingKeys explícitos, no será serializada ni deserializada. Por lo tanto, para propiedades privadas, es necesario declarar CodingKeys e incluirlas en la enumeración si es necesario.
¿Es posible implementar Codable solo para decodificación (solo lectura)?
Sí, para esto solo es necesario implementar init(from:) y hacer que el tipo conforme al protocolo Decodable en lugar de Codable.
struct ReadOnlyModel: Decodable { let id: Int }
Caso negativo
El desarrollador añadió una propiedad calculada al modelo, sin implementar los métodos personalizados de encode y decode, esperando que la manipulación automática de Codable funcionara.
Ventajas:
Desventajas:
Caso positivo
El desarrollador implementa CodingKeys personalizadas y métodos personalizados de encode/decode para casos complejos, donde las propiedades no coinciden con las claves, hay campos calculados, y se aplica la herencia.
Ventajas:
Desventajas: