encode(to:) et init(from:) manuels
Prenez le contrôle total de la logique de sérialisation.
encode(to:) et init(from:) manuels est une leçon Swift Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Swift Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Swift Academy comprend 4 leçons au total.
Quand la synthèse ne suffit pas
Parfois, la structure JSON ne correspond pas à vos propriétés : vous avez besoin de transformations calculées, de valeurs de repli par défaut ou d’un aplatissement. Vous devez alors implémenter manuellement encode(to:) et init(from:).
import Foundation
struct Temperature: Codable {
var celsius: Double
}
print("Manual coding gives full control")Déclarer CodingKeys en premier
Le codage manuel commence par une énumération CodingKeys. Les conteneurs de clés utilisent ces clés pour lire et écrire les valeurs.
import Foundation
struct User {
var name: String
var age: Int
enum CodingKeys: String, CodingKey {
case name
case age
}
}
print(User.CodingKeys.name.stringValue)Implémenter init(from:)
init(from decoder:) obtient un conteneur de clés avec container(keyedBy:), puis décode chaque propriété à partir de sa clé.
import Foundation
struct User: Decodable {
var name: String
var age: Int
enum CodingKeys: String, CodingKey { case name, age }
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
name = try c.decode(String.self, forKey: .name)
age = try c.decode(Int.self, forKey: .age)
}
}
let u = try JSONDecoder().decode(User.self, from: "{\"name\":\"Ada\",\"age\":36}".data(using: .utf8)!)
print(u.name, u.age)Implémenter encode(to:)
encode(to encoder:) obtient un conteneur de clés modifiable avec container(keyedBy:) et écrit chaque propriété avec encode(_:forKey:).
import Foundation
struct User: Encodable {
var name: String
var age: Int
enum CodingKeys: String, CodingKey { case name, age }
func encode(to encoder: Encoder) throws {
var c = encoder.container(keyedBy: CodingKeys.self)
try c.encode(name, forKey: .name)
try c.encode(age, forKey: .age)
}
}
let data = try JSONEncoder().encode(User(name: "Ada", age: 36))
print(String(data: data, encoding: .utf8)!)Sérialisation complète écrite manuellement
L’implémentation des deux méthodes rend le type entièrement sérialisable, avec une logique personnalisée aux deux extrémités.
import Foundation
struct Point: Codable {
var x: Int
var y: Int
enum CodingKeys: String, CodingKey { case x, y }
init(x: Int, y: Int) { self.x = x; self.y = y }
init(from d: Decoder) throws {
let c = try d.container(keyedBy: CodingKeys.self)
x = try c.decode(Int.self, forKey: .x)
y = try c.decode(Int.self, forKey: .y)
}
func encode(to e: Encoder) throws {
var c = e.container(keyedBy: CodingKeys.self)
try c.encode(x, forKey: .x)
try c.encode(y, forKey: .y)
}
}
let back = try JSONDecoder().decode(Point.self, from: try JSONEncoder().encode(Point(x: 1, y: 2)))
print(back.x, back.y)Fournir des valeurs par défaut
Utilisez decodeIfPresent avec l’opérateur de coalescence pour fournir une valeur par défaut lorsqu’une clé est absente, au lieu de lever une erreur.
import Foundation
struct Settings: Decodable {
var theme: String
enum CodingKeys: String, CodingKey { case theme }
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
theme = try c.decodeIfPresent(String.self, forKey: .theme) ?? "light"
}
}
let s = try JSONDecoder().decode(Settings.self, from: "{}".data(using: .utf8)!)
print(s.theme)Transformer les valeurs
Le décodage manuel vous permet de transformer le JSON brut en une représentation plus riche — ici, une valeur d’entrée en Fahrenheit est stockée en Celsius.
import Foundation
struct Reading: Decodable {
var celsius: Double
enum CodingKeys: String, CodingKey { case fahrenheit }
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
let f = try c.decode(Double.self, forKey: .fahrenheit)
celsius = (f - 32) * 5 / 9
}
}
let r = try JSONDecoder().decode(Reading.self, from: "{\"fahrenheit\":212}".data(using: .utf8)!)
print(r.celsius)Aplatir un JSON imbriqué
Vous pouvez lire un conteneur imbriqué avec nestedContainer(keyedBy:forKey:) et faire remonter ses valeurs dans une structure Swift plate.
import Foundation
struct Profile: Decodable {
var city: String
enum Keys: String, CodingKey { case address }
enum AddressKeys: String, CodingKey { case city }
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: Keys.self)
let a = try c.nestedContainer(keyedBy: AddressKeys.self, forKey: .address)
city = try a.decode(String.self, forKey: .city)
}
}
let json = "{\"address\":{\"city\":\"Rome\"}}"
let p = try JSONDecoder().decode(Profile.self, from: json.data(using: .utf8)!)
print(p.city)Encoder dans un conteneur imbriqué
L’encodage peut effectuer l’opération inverse : écrire une structure plate sous forme d’objet JSON imbriqué avec nestedContainer(keyedBy:forKey:).
import Foundation
struct Profile: Encodable {
var city: String
enum Keys: String, CodingKey { case address }
enum AddressKeys: String, CodingKey { case city }
func encode(to encoder: Encoder) throws {
var c = encoder.container(keyedBy: Keys.self)
var a = c.nestedContainer(keyedBy: AddressKeys.self, forKey: .address)
try a.encode(city, forKey: .city)
}
}
let data = try JSONEncoder().encode(Profile(city: "Rome"))
print(String(data: data, encoding: .utf8)!)Valider pendant le décodage
Comme init(from:) n’est qu’un initialiseur, vous pouvez valider les valeurs et lever une erreur personnalisée lorsqu’elles sont hors limites.
import Foundation
struct Score: Decodable {
var value: Int
enum CodingKeys: String, CodingKey { case value }
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
let v = try c.decode(Int.self, forKey: .value)
guard (0...100).contains(v) else {
throw DecodingError.dataCorruptedError(forKey: .value, in: c, debugDescription: "out of range")
}
value = v
}
}
let s = try JSONDecoder().decode(Score.self, from: "{\"value\":80}".data(using: .utf8)!)
print(s.value)Mélanger codage manuel et synthétisé
Un type peut implémenter manuellement une seule méthode et laisser le compilateur synthétiser l’autre — par exemple, utiliser un init(from:) personnalisé avec un encodage synthétisé.
import Foundation
struct Flag: Codable {
var on: Bool
enum CodingKeys: String, CodingKey { case on }
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
on = (try? c.decode(Bool.self, forKey: .on)) ?? false
}
init(on: Bool) { self.on = on }
}
let data = try JSONEncoder().encode(Flag(on: true))
print(String(data: data, encoding: .utf8)!)Vérification rapide : codage manuel
Vérifiez votre compréhension des méthodes de sérialisation écrites manuellement.
Récapitulatif : encode(to:) et init(from:) manuels
Vous avez appris à contrôler entièrement le codage :
- Déclarez
CodingKeys, puis implémentezinit(from:)etencode(to:). - Utilisez
container(keyedBy:)etencode/decode(_:forKey:). decodeIfPresentassocié à??fournit des valeurs par défaut ;nestedContainerpermet d’aplatir ou d’imbriquer le JSON.- Vous pouvez valider et transformer les valeurs, ainsi que combiner des méthodes manuelles et synthétisées.
Questions Fréquemment Posées
La leçon « encode(to:) et init(from:) manuels » est-elle gratuite ?
Oui — le texte complet de « encode(to:) et init(from:) manuels » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Swift Academy, passe à CoddyKit PRO. Le cours Swift Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « encode(to:) et init(from:) manuels » ?
Prenez le contrôle total de la logique de sérialisation. Tu pratiques Swift Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Swift Academy ?
Aucune expérience préalable n'est requise. Swift Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « encode(to:) et init(from:) manuels » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Swift Academy ?
Oui. Chaque leçon Swift Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- CodingKeys pour renommer
- Stratégies de décodage des clés et des dates
- encode(to:) et init(from:) manuels
- Décodage de JSON hétérogène