Il protocollo Codable è stato introdotto in Swift per semplificare il processo di serializzazione e deserializzazione dei dati, come JSON o Property List. In precedenza, era necessario implementare manualmente il parsing, il che era laborioso, soggetto a errori e poco leggibile. L'automazione di questo processo ha permesso di sviluppare codice più sicuro e conciso.
Il problema risiede nel fatto che, quando si utilizza Codable in modo automatico, tutte le proprietà devono essere anch'esse Codable, e qualsiasi violazione di questa catena richiede un'implementazione esplicita dei metodi di decodifica e codifica. Inoltre, ci sono peculiarità quando si lavora con strutture, classi con ereditarietà e anche durante l'abbinamento personalizzato delle chiavi.
La soluzione consiste nell'utilizzare Codable per modelli semplici, prestando attenzione a quali proprietà devono essere serializzate e, nel caso di modelli complessi, implementare i metodi encode(to:) e init(from:), oltre a utilizzare i CodingKeys per l'abbinamento delle chiavi.
Esempio di codice:
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" } }
Caratteristiche chiave:
Un classe con ereditarietà e proprietà uniche del discendente può essere serializzata correttamente utilizzando Codable automaticamente?
No, per le classi con ereditarietà Swift richiede un'implementazione manuale di encode(to:) e init(from:) nelle sottoclassi, altrimenti le proprietà del genitore e del discendente non vengono serializzate correttamente. Esempio:
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) } }
Cosa succede se una proprietà in una struttura è contrassegnata come private mentre si utilizza Codable automatico?
Se la proprietà è privata e non è dichiarata come var/let con espliciti CodingKeys, non verrà serializzata o deserializzata. Pertanto, per le proprietà private è necessario dichiarare CodingKeys e includerli nell'enumerazione quando necessario.
È possibile implementare Codable solo per la decodifica (solo lettura)?
Sì, per farlo è sufficiente implementare solo init(from:) e conformare il tipo al protocollo Decodable invece di Codable.
struct ReadOnlyModel: Decodable { let id: Int }
** Caso negativo
Un sviluppatore ha aggiunto una proprietà calcolata al modello senza implementare metodi personalizzati di encode e decode, sperando in una gestione automatica di Codable.
Vantaggi:
Svantaggi:
** Caso positivo
Un sviluppatore implementa CodingKeys personalizzati e metodi personalizzati di encode/decode per casi complessi, dove le proprietà non coincidono con le chiavi, ci sono campi calcolati e si utilizza l'ereditarietà.
Vantaggi:
Svantaggi: