JSONSerialization: ce este, metodele clasei Foundation și cum funcționează

Autor: IT Sectr Publicat: 2026-03-15 Timp de citire: 8 min

JSONSerialization — o clasă iOS încorporată din framework-ul Foundation, destinată conversiei JSON în obiecte Foundation și invers. Această API este mecanismul de bază pentru lucrul cu JSON pe platformele Apple fără a conecta biblioteci terțe, suportând parsarea dicționarelor, array-urilor și tipurilor primitive. Conform Apple Developer, 2024, JSONSerialization suportă lucrul cu Data, fluxuri și opțiuni de citire pentru procesarea flexibilă a datelor JSON.

Principalele puncte

  • JSONSerialization — clasă încorporată Foundation pentru parsarea JSON pe iOS și macOS
  • jsonObject — metodă de conversie a datelor JSON în dicționare și array-uri Foundation
  • data — metodă de serializare a obiectelor Foundation înapoi în date JSON
  • isValidJSONObject — verificare dacă un obiect poate fi serializat în JSON
  • Codable — alternativă modernă cu serializare tipizată în Swift

Ce este JSONSerialization

JSONSerialization — este o clasă din framework-ul Foundation, disponibilă pe iOS, macOS, tvOS și watchOS. Oferă metode pentru conversia datelor JSON în obiecte Foundation (NSDictionary, NSArray, NSString, NSNumber) și invers. Clasa a apărut în iOS 5 și până la introducerea Codable (Swift 4) a rămas principala modalitate de lucru cu JSON pe platformele Apple. În ciuda vechimii, JSONSerialization rămâne utilizat în proiecte legacy pe Objective-C și în scenarii care necesită procesare dinamică JSON fără o schemă fixă de model.

Când se utilizează JSONSerialization

În ciuda apariției Codable, JSONSerialization rămâne relevant în mai multe scenarii. Structura dinamică JSON — când formatul răspunsului se schimbă sau este necunoscut dinainte — necesită accesarea dicționarelor prin chei, ceea ce este mai simplu de făcut prin JSONSerialization. Clasa este utilizată și în proiecte Objective-C unde Codable nu este disponibil, și la lucrul cu fluxuri pentru parsarea etapizată a fișierelor JSON mari. În teste și machete, isValidJSONObject și data(withJSONObject:options:) permit generarea rapidă a fixture JSON fără a conecta biblioteci terțe, ceea ce accelerează dezvoltarea și prototiparea.

swift
import Foundation

// Structura de bază a utilizării JSONSerialization
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("Eroare de parsare JSON: \(error)")
}

Metodele principale ale clasei

JSONSerialization oferă patru metode principale pentru lucrul cu JSON. Metoda principală — jsonObject(with:options:), care convertește Data în obiecte Foundation. Metoda data(withJSONObject:options:) efectuează serializarea inversă. isValidJSONObject(_:) verifică dacă un obiect poate fi serializat. writeJSONObject(_:to:options:error:) scrie JSON direct într-un flux. Pentru citirea JSON din InputStream există metoda jsonObject(with:options:), care acceptă un flux în loc de Data, fiind convenabilă la integrarea cu cereri de rețea care returnează date în flux.

JSONObject și JSONData

Metoda jsonObject primește Data și returnează Any — de obicei NSDictionary sau NSArray. Pentru lucrul sigur, rezultatul este convertit la tipul așteptat prin conversie condiționată. Metoda data primește un obiect Foundation și returnează Data cu reprezentarea JSON. Opțiunea .prettyPrinted adaugă formatare cu indentări pentru lizibilitate.

swift
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("Produs: \(name)")
        }
    }
}

// Serializare inversă: obiect -> JSON
let outputDict: [String: Any] = ["status": "ok", "count": 42]
if let outputData = try? JSONSerialization
    .data(withJSONObject: outputDict,
                options: .prettyPrinted) {
    String(data: outputData, encoding: .utf8)
}

Exemple de parsare JSON

Parsarea de bază a unui dicționar cu tipuri primitive — cea mai frecventă operație cu JSONSerialization. După primirea Data prin URLSession, dezvoltatorul apelează jsonObject și convertește rezultatul la tipul așteptat. Pentru array-uri de obiecte se utilizează conversia la [[String: Any]], după care fiecare element este procesat într-o buclă. Această abordare este flexibilă, dar necesită gestionarea manuală a tipurilor.

Parsarea structurilor imbricate

API-urile reale returnează obiecte JSON imbricate complexe cu array-uri, date și câmpuri opționale. JSONSerialization procesează corect orice adâncime de imbricare, dar dezvoltatorul trebuie să convertească independent fiecare nivel la tipul necesar. Pentru simplificarea acestei sarcini, Apple recomandă utilizarea Codable pentru date tipizate, iar JSONSerialization — doar pentru structuri dinamice.

swift
// Parsarea răspunsului de la API
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("Utilizator: \(name) (ID: \(userId))")

    } catch let error as ParsingError {
        print("Parsare eșuată: \(error)")
    } catch {
        print("Eroare neașteptată: \(error)")
    }
}

enum ParsingError: Error {
    case missingField
    case invalidType
}

Gestionarea erorilor

JSONSerialization aruncă erori la JSON invalid, nepotrivire de tipuri sau depășirea adâncimii de imbricare. Erorile sunt de tipul CocoaError și conțin un cod cu descrierea problemei. Dezvoltatorul este obligat să le gestioneze prin construcția do-catch, altfel aplicația se va termina anormal. Cele mai frecvente erori: NSPropertyListReadCorruptError (JSON incorect) și NSPropertyListReadUnknownError. Fiecare tip de eroare necesită propria strategie de gestionare: la format invalid trebuie solicitată retrimiterea datelor, iar la nepotrivirea structurii — actualizarea modelului de parsare.

Tipuri de erori la deserializare

JSON invalid — cea mai frecventă cauză a eșecurilor: virgulă lipsă, caracter în plus sau ghilimele neescapate strică întreaga parsare. Al doilea tip de erori — nepotrivirea cu structura așteptată: de exemplu, serverul a returnat un array în loc de dicționar. JSONSerialization.fragmentsAllowed permite citirea JSON a cărui rădăcină nu este un dicționar sau array, ci o valoare primitivă. Dezvoltatorul poate întâlni și eroarea de depășire a adâncimii de imbricare, când JSON conține prea multe niveluri de ierarhie.

Opțiuni de citire și scriere

JSONSerialization oferă mai multe opțiuni pentru configurarea parsării. .mutableContainers returnează NSMutableDictionary și NSMutableArray în locul versiunilor imutabile, ceea ce este util la modificarea datelor după parsare. .mutableLeaves face modificabile valorile text. .fragmentsAllowed permite JSON a cărui rădăcină nu este un obiect sau array, ci un șir sau număr — convenabil pentru răspunsuri API simple. Opțiunile .withoutEscapingSlashes și .sortedKeys sunt disponibile pentru metoda data(withJSONObject:options:), controlând formatarea JSON serializat. Opțiunile sunt transmise printr-o mască de biți, permițând combinarea mai multor valori prin operatorul | pentru o configurare flexibilă a parsării.

swift
// Gestionarea diferitelor tipuri de erori
func safeParse(jsonData: Data) {
    do {
        let object = try JSONSerialization
            .jsonObject(with: jsonData,
                           options: .fragmentsAllowed)

        if let dictionary = object as? [String: Any] {
            print("Dicționar cu \(dictionary.count) chei")
        } else if let array = object as? [Any] {
            print("Array cu \(array.count) elemente")
        }

    } catch CocoaError.propertyListReadCorrupt {
        print("Date JSON corupte")
    } catch let error as CocoaError {
        print("Eroare Cocoa: \(error)")
    } catch {
        print("Eroare necunoscută: \(error)")
    }
}

// Verificarea validității obiectului înainte de serializare
let testObject: [String: Any] = ["key": "value", "nested": ["a": 1]]
if JSONSerialization.isValidJSONObject(testObject) {
    print("Obiect JSON valid")
}

Performanța JSONSerialization este influențată de dimensiunea datelor și frecvența apelurilor. La parsarea unică a unui răspuns mic de server, diferența este nesemnificativă, dar la procesarea zecilor de megaocteți de JSON sau apelurilor frecvente în bucle, trebuie luate în considerare costurile de conversie a tipurilor. JSONSerialization funcționează sincron în firul curent, de aceea pentru documente mari se recomandă mutarea parsării într-o coadă de fundal prin DispatchQueue.global(). Alternativ, se poate utiliza InputStream pentru procesarea în flux fără încărcarea întregului fișier în memorie, ceea ce este critic pentru aplicațiile cu resurse limitate. Pentru scrierea JSON într-un fișier sau flux de rețea, metoda writeJSONObject(_:to:options:error:) permite direcționarea directă a datelor serializate către OutputStream fără a crea un obiect Data intermediar, reducând consumul de memorie la lucrul cu documente mari.

Întrebări frecvente

Ce este JSONSerialization în iOS?

JSONSerialization — este o clasă Foundation pentru conversia datelor JSON în obiecte Foundation (NSDictionary, NSArray) și invers. Funcționează pe iOS, macOS, tvOS și watchOS fără a conecta biblioteci suplimentare.

Cu ce se deosebește JSONSerialization de Codable?

Codable — este un protocol Swift pentru serializare automată tipizată, care se compilează în cod sigur tipizat. JSONSerialization lucrează cu tipuri dinamice Any și necesită conversie manuală. Codable este preferat pentru proiecte noi, JSONSerialization — pentru Objective-C și date dinamice.

Cum să gestionezi o eroare la parsarea JSON?

Folosiți construcția do-catch la apelarea jsonObject. Erorile JSONSerialization aparțin CocoaError. Pentru depanare verificați NSPropertyListReadCorruptError, care indică un format invalid al datelor JSON.

Suportă JSONSerialization structuri imbricate?

Da, JSONSerialization suportă orice adâncime de imbricare a dicționarelor și array-urilor. Toate obiectele imbricate sunt convertite în tipurile Foundation corespunzătoare (NSDictionary, NSArray, NSString, NSNumber), păstrând structura JSON originală.

Când să folosim JSONSerialization în loc de Codable?

JSONSerialization este potrivit la structura dinamică JSON, în proiecte Objective-C, la lucrul cu fluxuri și pentru verificarea validității JSON prin isValidJSONObject. Pentru structuri tipizate cu schemă cunoscută este preferat Codable.

Rezumat

  • JSONSerialization — clasă încorporată Foundation pentru lucrul de bază cu JSON pe platformele Apple
  • jsonObject — metodă principală de parsare, care convertește Data în dicționare și array-uri Foundation
  • data — metodă de serializare inversă a obiectelor Foundation în date JSON cu opțiuni de formatare
  • isValidJSONObject — predicat pentru verificarea posibilității de serializare a unui obiect în JSON
  • Gestionarea erorilor este obligatorie prin do-catch pentru prevenirea terminării anormale a aplicației
  • Codable — alternativă modernă tipizată pentru proiecte Swift cu schemă de date cunoscută

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și