Manuelles encode(to:) und init(from:)
Übernehmen Sie die vollständige Kontrolle über die Serialisierungslogik.
Manuelles encode(to:) und init(from:) ist eine kostenlose Swift Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Swift Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Swift Academy-Kurs umfasst insgesamt 4 Lektionen.
Wenn die Synthese nicht ausreicht
Manchmal entspricht die Struktur des JSON nicht Ihren Eigenschaften – dann benötigen Sie berechnete Umwandlungen, Standardwerte oder eine Abflachung der Struktur. In diesem Fall implementieren Sie encode(to:) und init(from:) von Hand.
import Foundation
struct Temperature: Codable {
var celsius: Double
}
print("Manual coding gives full control")CodingKeys zuerst deklarieren
Die manuelle Codierung beginnt mit einem CodingKeys-Enum. Die Keyed Container verwenden diese Schlüssel, um Werte zu lesen und zu schreiben.
import Foundation
struct User {
var name: String
var age: Int
enum CodingKeys: String, CodingKey {
case name
case age
}
}
print(User.CodingKeys.name.stringValue)init(from:) implementieren
init(from decoder:) ruft mit container(keyedBy:) einen Keyed Container ab und dekodiert anschließend jede Eigenschaft über ihren Schlüssel.
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)encode(to:) implementieren
encode(to encoder:) ruft mit container(keyedBy:) einen veränderbaren Keyed Container ab und schreibt jede Eigenschaft mit 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)!)Codable vollständig von Hand
Wenn Sie beide Methoden implementieren, ist der Typ vollständig Codable und kann an beiden Enden eigene Logik verwenden.
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)Standardwerte bereitstellen
Verwenden Sie decodeIfPresent zusammen mit dem Nil-Coalescing-Operator, um bei einem fehlenden Schlüssel einen Standardwert bereitzustellen, anstatt einen Fehler auszulösen.
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)Werte umwandeln
Durch manuelles Dekodieren können Sie rohes JSON in eine aussagekräftigere Darstellung umwandeln – hier wird eine Eingabe in Fahrenheit als Celsius gespeichert.
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)Verschachteltes JSON abflachen
Mit nestedContainer(keyedBy:forKey:) können Sie einen verschachtelten Container lesen und seine Werte in eine flache Swift-Struktur übernehmen.
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)In einen verschachtelten Container encodieren
Die Encodierung kann auch die umgekehrte Richtung übernehmen: Mit nestedContainer(keyedBy:forKey:) schreiben Sie eine flache Struktur als verschachteltes JSON-Objekt.
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)!)Während des Dekodierens validieren
Da init(from:) einfach ein Initializer ist, können Sie Werte validieren und einen eigenen Fehler auslösen, wenn sie außerhalb des zulässigen Bereichs liegen.
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)Manuelle und synthetisierte Methoden kombinieren
Ein Typ kann nur eine der beiden Methoden manuell implementieren und die andere vom Compiler synthetisieren lassen – beispielsweise ein eigenes init(from:) bei synthetisierter Encodierung.
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)!)Kurzer Check: Manuelle Codierung
Testen Sie Ihr Verständnis der von Hand geschriebenen Codable-Methoden.
Zusammenfassung: Manuelles encode(to:) und init(from:)
Sie haben gelernt, die Codierung vollständig zu kontrollieren:
- Deklarieren Sie
CodingKeysund implementieren Sie anschließendinit(from:)undencode(to:). - Verwenden Sie
container(keyedBy:)sowieencode/decode(_:forKey:). decodeIfPresentzusammen mit??stellt Standardwerte bereit;nestedContainerflacht JSON ab oder verschachtelt es.- Sie können Werte validieren und umwandeln sowie manuelle und synthetisierte Methoden kombinieren.
Häufig gestellte Fragen
Ist die Lektion „Manuelles encode(to:) und init(from:)“ kostenlos?
Ja — der vollständige Text von „Manuelles encode(to:) und init(from:)“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Swift Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Swift Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Manuelles encode(to:) und init(from:)“?
Übernehmen Sie die vollständige Kontrolle über die Serialisierungslogik. Du übst Swift Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Swift Academy zu starten?
Keine Vorkenntnisse erforderlich. Swift Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Manuelles encode(to:) und init(from:)“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Swift Academy-Lektion Code schreiben und ausführen?
Ja. Jede Swift Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- CodingKeys zum Umbenennen
- Strategien für Schlüssel- und Datumsdecodierung
- Manuelles encode(to:) und init(from:)
- Heterogenes JSON decodieren