JSONSerialization — egy beépített iOS osztály a Foundation keretrendszerből, amely a JSON Foundation objektumokká való átalakítására és visszafelé szolgál. Ez az API az alapvető mechanizmus a JSON-nal való munkához Apple platformokon, külső könyvtárak csatlakoztatása nélkül, támogatva szótárak, tömbök és primitív típusok feldolgozását. A Apple Developer, 2024 szerint a JSONSerialization támogatja a Data-val, adatfolyamokkal és olvasási opciókkal való munkát a JSON-adatok rugalmas feldolgozásához.
Főbb pontok
JSONSerialization — egy osztály a Foundation keretrendszerből, amely iOS, macOS, tvOS és watchOS rendszereken érhető el. Metódusokat biztosít a JSON Data Foundation objektumokká (NSDictionary, NSArray, NSString, NSNumber) és visszafelé történő átalakításához. Az osztály az iOS 5-ben jelent meg, és a Codable (Swift 4) bevezetéséig a JSON-nal való munka fő módja maradt az Apple platformokon. Kora ellenére a JSONSerialization továbbra is keresett az Objective-C régi projektekben és olyan forgatókönyvekben, ahol dinamikus JSON-feldolgozás szükséges rögzített modellséma nélkül.
A Codable megjelenése ellenére a JSONSerialization továbbra is releváns több forgatókönyvben. Dinamikus JSON-struktúra — amikor a válasz formátuma változik vagy előre nem ismert — kulcsokon keresztüli hozzáférést igényel a szótárakhoz, ami egyszerűbben megtehető a JSONSerialization segítségével. Az osztályt Objective-C projektekben is használják, ahol a Codable nem érhető el, valamint adatfolyamokkal való munka során nagy JSON-fájlok szakaszos feldolgozásához. Tesztekben és makettekben az isValidJSONObject és a data(withJSONObject:options:) lehetővé teszi JSON-fixtúrák gyors generálását külső könyvtárak csatlakoztatása nélkül, ami felgyorsítja a fejlesztést és prototípuskészítést.
import Foundation
// A JSONSerialization használatának alapstruktúrája
let jsonString = """
{
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}
"""
guard let jsonData = jsonString.data(using: .utf8) else {
return
}
do {
let json = try JSONSerialization
.jsonObject(with: jsonData,
options: .mutableContainers)
print(json)
} catch {
print("JSON feldolgozási hiba: \(error)")
}
JSONSerialization négy fő metódust biztosít a JSON-nal való munkához. A fő metódus — jsonObject(with:options:), amely a Data-t Foundation objektumokká alakítja. A data(withJSONObject:options:) metódus végrehajtja a fordított szerializációt. Az isValidJSONObject(_:) ellenőrzi, hogy egy objektum szerializálható-e. A writeJSONObject(_:to:options:error:) közvetlenül egy adatfolyamba írja a JSON-t. Az InputStream-ből történő JSON olvasáshoz létezik a jsonObject(with:options:) metódus, amely Data helyett adatfolyamot fogad, ami kényelmes a stream adatokat visszaadó hálózati kérésekkel való integrációkor.
A jsonObject metódus Data-t fogad és Any-t ad vissza — általában NSDictionary vagy NSArray értéket. A biztonságos munkához az eredmény feltételes konverzióval a várt típusra alakítandó. A data metódus egy Foundation objektumot fogad és Data-t ad vissza JSON reprezentációval. A .prettyPrinted opció olvashatóság érdekében behúzásokkal ellátott formázást ad hozzá.
let jsonString = """
{
"products": [
{"id": 1, "name": "iPhone", "price": 999},
{"id": 2, "name": "iPad", "price": 799}
]
}
"""
let data = Data(jsonString.utf8)
if let json = try? JSONSerialization
.jsonObject(with: data) as? [String: Any],
let products = json["products"] as? [[String: Any]] {
for product in products {
if let name = product["name"] as? String {
print("Termék: \(name)")
}
}
}
// Fordított szerializáció: objektum -> JSON
let outputDict: [String: Any] = ["status": "ok", "count": 42]
if let outputData = try? JSONSerialization
.data(withJSONObject: outputDict,
options: .prettyPrinted) {
String(data: outputData, encoding: .utf8)
}
Alapvető feldolgozás egy szótár primitív típusokkal — a leggyakoribb művelet a JSONSerialization-nel. Miután a Data-t URLSession-en keresztül megkapta, a fejlesztő meghívja a jsonObject-et és az eredményt a várt típusra alakítja. Objektumok tömbjei esetén [[String: Any]]-ra konvertálás használatos, majd minden elem egy ciklusban kerül feldolgozásra. Ez a megközelítés rugalmas, de kézi típuskezelést igényel.
A valódi API-k összetett beágyazott JSON objektumokat adnak vissza tömbökkel, dátumokkal és opcionális mezőkkel. JSONSerialization helyesen dolgoz fel bármilyen beágyazási mélységet, de a fejlesztőnek minden szintet önállóan a szükséges típusra kell alakítania. A feladat egyszerűsítése érdekében az Apple a Codable használatát ajánlja típusos adatokhoz, a JSONSerialization-t pedig csak dinamikus struktúrákhoz.
// API-válasz feldolgozása
func parseUserResponse(data: Data) {
do {
guard let json = try JSONSerialization
.jsonObject(with: data) as? [String: Any]
else { return }
guard let userId = json["id"] as? Int,
let name = json["name"] as? String
else {
throw ParsingError.missingField
}
print("Felhasználó: \(name) (ID: \(userId))")
} catch let error as ParsingError {
print("A feldolgozás sikertelen: \(error)")
} catch {
print("Váratlan hiba: \(error)")
}
}
enum ParsingError: Error {
case missingField
case invalidType
}
JSONSerialization hibákat dob érvénytelen JSON, típus-eltérés vagy a beágyazási mélység túllépése esetén. A hibák a CocoaError típusba tartoznak és kódot tartalmaznak a probléma leírásával. A fejlesztő köteles ezeket do-catch konstrukción keresztül kezelni, ellenkező esetben az alkalmazás hirtelen megszakad. A leggyakoribb hibák: NSPropertyListReadCorruptError (helytelen JSON) és NSPropertyListReadUnknownError. Minden hibatípus saját kezelési stratégiát igényel: érvénytelen formátum esetén az adatok újraküldését kell kérni, struktúra-eltérés esetén pedig frissíteni kell a feldolgozási modellt.
Érvénytelen JSON — a meghibásodások leggyakoribb oka: hiányzó vessző, felesleges karakter vagy nem escape-elt idézőjel tönkreteszi a teljes feldolgozást. A második hibatípus — eltérés a várt struktúrától: például a szerver egy tömböt adott vissza szótár helyett. A JSONSerialization.fragmentsAllowed lehetővé teszi olyan JSON olvasását, amelynek gyökere nem szótár vagy tömb, hanem primitív érték. A fejlesztő találkozhat a beágyazási mélység túllépésének hibájával is, amikor a JSON túl sok hierarchiaszintet tartalmaz.
A JSONSerialization több opciót kínál a feldolgozás konfigurálásához. .mutableContainers a nem módosítható verziók helyett NSMutableDictionary és NSMutableArray értékeket ad vissza, ami hasznos az adatok feldolgozás utáni módosításakor. A .mutableLeaves módosíthatóvá teszi a szöveges értékeket. A .fragmentsAllowed lehetővé teszi olyan JSON-t, amelynek gyökere nem objektum vagy tömb, hanem szöveg vagy szám — kényelmes egyszerű API-válaszokhoz. A .withoutEscapingSlashes és .sortedKeys opciók a data(withJSONObject:options:) metódushoz érhetők el, irányítva a szerializált JSON formázását. Az opciók bitmaszkon keresztül kerülnek átadásra, lehetővé téve több érték kombinálását a | operátoron keresztül a rugalmas feldolgozási konfigurációhoz.
// Különböző hibatípusok kezelése
func safeParse(jsonData: Data) {
do {
let object = try JSONSerialization
.jsonObject(with: jsonData,
options: .fragmentsAllowed)
if let dictionary = object as? [String: Any] {
print("Szótár \(dictionary.count) kulccsal")
} else if let array = object as? [Any] {
print("Tömb \(array.count) elemmel")
}
} catch CocoaError.propertyListReadCorrupt {
print("Sérült JSON adat")
} catch let error as CocoaError {
print("Cocoa hiba: \(error)")
} catch {
print("Ismeretlen hiba: \(error)")
}
}
// Objektum érvényességének ellenőrzése szerializáció előtt
let testObject: [String: Any] = ["key": "value", "nested": ["a": 1]]
if JSONSerialization.isValidJSONObject(testObject) {
print("Érvényes JSON objektum")
}
A JSONSerialization teljesítményét az adatok mérete és a hívások gyakorisága befolyásolja. Egy kis szerverválasz egyszeri feldolgozásakor a különbség nem észrevehető, de több tíz megabájt JSON feldolgozásakor vagy gyakori hívások esetén ciklusokban figyelembe kell venni a típuskonverzió többletköltségeit. A JSONSerialization szinkron módon működik az aktuális szálon, ezért nagy dokumentumok esetén ajánlott a feldolgozást háttérvárólistára helyezni a DispatchQueue.global() segítségével. Alternatívaként InputStream használható a stream feldolgozáshoz anélkül, hogy a teljes fájlt a memóriába töltené, ami kritikus a korlátozott erőforrásokkal rendelkező alkalmazások számára. JSON fájlba vagy hálózati adatfolyamba írásához a writeJSONObject(_:to:options:error:) metódus lehetővé teszi a szerializált adatok közvetlen OutputStream-be irányítását köztes Data objektum létrehozása nélkül, ami csökkenti a memóriahasználatot nagy dokumentumokkal való munka során.
Gyakran ismételt kérdések
JSONSerialization — egy Foundation osztály a JSON Data Foundation objektumokká (NSDictionary, NSArray) és visszafelé történő alakításához. iOS, macOS, tvOS és watchOS rendszereken működik további könyvtárak csatlakoztatása nélkül.
Codable — egy Swift protokoll automatikus típusos szerializációhoz, amely típusbiztos kódra fordul. A JSONSerialization dinamikus Any típusokkal dolgozik és kézi konverziót igényel. A Codable új projektekhez ajánlott, a JSONSerialization — Objective-C és dinamikus adatokhoz.
Használja a do-catch konstrukciót a jsonObject hívásakor. A JSONSerialization hibái a CocoaError típusba tartoznak. Hibakereséshez ellenőrizze az NSPropertyListReadCorruptError-t, amely a JSON-adatok érvénytelen formátumát jelzi.
Igen, JSONSerialization támogatja a szótárak és tömbök bármilyen beágyazási mélységét. Minden beágyazott objektum a megfelelő Foundation típusokra (NSDictionary, NSArray, NSString, NSNumber) konvertálódik, megtartva az eredeti JSON struktúrát.
JSONSerialization alkalmas dinamikus JSON struktúrához, Objective-C projektekben, adatfolyamokkal való munkához és a JSON érvényességének ellenőrzéséhez az isValidJSONObject segítségével. Ismert sémával rendelkező típusos struktúrákhoz a Codable ajánlott.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is