Arbeiten mit JSON in Swift: Parsing und Serialisierung in der Praxis
JSON (JavaScript Object Notation) ist ein leichtgewichtiges Datenaustauschformat, das sich zum De-facto-Standard für die Kommunikation zwischen Client und Server in der mobilen und Webentwicklung entwickelt hat. Im Apple-Ökosystem (iOS, macOS, watchOS, tvOS) erfolgt die Arbeit mit JSON über leistungsstarke integrierte Mechanismen. In diesem Artikel werden wir detailliert betrachten, wie man JSON in Swift anhand realer Beispiele parst und serialisiert, sowohl mit dem modernen Protokoll Codable als auch mit dem klassischen JSONSerialization.
Der Artikel richtet sich an Entwickler, die bereits mit den Grundlagen von Swift vertraut sind und sicher mit Netzwerkanfragen und lokaler Datenspeicherung im JSON-Format arbeiten möchten.
1. Grundlagen von JSON und seine Rolle in Swift-Anwendungen
JSON ist ein textbasiertes Format, das auf zwei Strukturen basiert: Objekte (Schlüssel-Wert-Paare) und Arrays (geordnete Listen). In Swift entsprechen diesen Strukturen Dictionary und Array. Die Datentypen in JSON sind begrenzt: Zeichenketten, Zahlen, boolesche Werte, null, Objekte und Arrays.
Ein typisches Szenario für die Verwendung von JSON in iOS/macOS-Anwendungen sieht wie folgt aus:
- Empfangen eines JSON-Strings vom Server (über URLSession).
- Parsen von JSON in Swift-Modelle (z. B. Strukturen oder Klassen).
- Verarbeiten der Daten und Anzeigen in der Benutzeroberfläche.
- Serialisierung (Rückumwandlung) von Modellen in JSON zum Senden an den Server.
Apple bietet zwei Hauptansätze für die Arbeit mit JSON: JSONSerialization (niedrigschwellig, aber flexibel) und Codable (hochschwellig, typsicher, empfohlen ab Swift 4+).
2. JSON-Parsing mit Codable (empfohlene Methode)
Das Protokoll Codable vereint Encodable (für Serialisierung) und Decodable (für Parsing). Dies ist der einfachste und sicherste Weg, mit JSON in Swift zu arbeiten.
Beispiel 1: Parsen eines einfachen JSON-Objekts
Angenommen, der Server gibt folgendes JSON zurück:
{ "userId": 1, "id": 1, "title": "Beispielaufgabe", "completed": false}Erstellen wir eine Modellstruktur, die Codable entspricht:
struct TodoItem: Codable { let userId: Int let id: Int let title: String let completed: Bool}Jetzt führen wir das Parsen des JSON-Strings durch:
let jsonString = """{ "userId": 1, "id": 1, "title": "Beispielaufgabe", "completed": false}"""
if let jsonData = jsonString.data(using: .utf8) { let decoder = JSONDecoder() do { let todo = try decoder.decode(TodoItem.self, from: jsonData) print("Aufgabe: \\(todo.title), erledigt: \\(todo.completed)") } catch { print("Parsing-Fehler: \\(error.localizedDescription)") }}Beispiel 2: Parsen eines Arrays von Objekten
Wenn der Server ein Array von Aufgaben zurückgibt:
[ {"userId": 1, "id": 1, "title": "Aufgabe 1", "completed": false}, {"userId": 1, "id": 2, "title": "Aufgabe 2", "completed": true}]Das Parsen erfolgt genauso einfach – man gibt den Array-Typ an:
let todoArray = try decoder.decode([TodoItem].self, from: jsonData)2.1. Benutzerdefinierte Schlüssel und snake_case
Häufig verwendet JSON das Format snake_case (z. B. user_id), während in Swift camelCase (userId) üblich ist. JSONDecoder kann Schlüssel automatisch umwandeln:
decoder.keyDecodingStrategy = .convertFromSnakeCaseFalls eine nicht standardmäßige Zuordnung erforderlich ist, verwenden Sie die Aufzählung CodingKeys:
struct User: Codable { let fullName: String let emailAddress: String
enum CodingKeys: