0Pricing
Swift Academy · Lektion

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 CodingKeys und implementieren Sie anschließend init(from:) und encode(to:).
  • Verwenden Sie container(keyedBy:) sowie encode/decode(_:forKey:).
  • decodeIfPresent zusammen mit ?? stellt Standardwerte bereit; nestedContainer flacht 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

  1. CodingKeys zum Umbenennen
  2. Strategien für Schlüssel- und Datumsdecodierung
  3. Manuelles encode(to:) und init(from:)
  4. Heterogenes JSON decodieren
← Zurück zu Swift Academy