JSONSerialization: cos'è, metodi della classe Foundation e come funziona

Autore: IT Sectr Pubblicato: 2026-03-15 Tempo di lettura: 8 min

JSONSerialization — una classe iOS integrata del framework Foundation progettata per convertire JSON in oggetti Foundation e viceversa. Questa API è il meccanismo di base per lavorare con JSON sulle piattaforme Apple senza librerie di terze parti, supportando l'analisi di dizionari, array e tipi primitivi. Secondo Apple Developer, 2024, JSONSerialization supporta il lavoro con Data, flussi e opzioni di lettura per l'elaborazione flessibile dei dati JSON.

Punti chiave

  • JSONSerialization — una classe Foundation integrata per analizzare JSON su iOS e macOS
  • jsonObject — metodo per convertire Data JSON in dizionari e array Foundation
  • data — metodo per serializzare gli oggetti Foundation nuovamente in Data JSON
  • isValidJSONObject — verifica se un oggetto può essere serializzato in JSON
  • Codable — alternativa moderna con serializzazione tipizzata in Swift

Cos'è JSONSerialization

JSONSerialization è una classe del framework Foundation disponibile su iOS, macOS, tvOS e watchOS. Fornisce metodi per convertire Data JSON in oggetti Foundation (NSDictionary, NSArray, NSString, NSNumber) e viceversa. La classe è apparsa in iOS 5 e fino all'introduzione di Codable (Swift 4) è rimasta il modo principale per lavorare con JSON sulle piattaforme Apple. Nonostante l'età, JSONSerialization rimane rilevante nei progetti legacy in Objective-C e negli scenari che richiedono un'elaborazione JSON dinamica senza uno schema di modello fisso.

Quando viene utilizzato JSONSerialization

Nonostante l'avvento di Codable, JSONSerialization rimane rilevante in diversi scenari. Struttura JSON dinamica — quando il formato della risposta cambia o è sconosciuto in anticipo — richiede l'accesso ai dizionari tramite chiavi, cosa più facile da fare attraverso JSONSerialization. La classe viene utilizzata anche in progetti Objective-C dove Codable non è disponibile e quando si lavora con flussi per l'analisi incrementale di grandi file JSON. Nei test e nei mockup, isValidJSONObject e data(withJSONObject:options:) consentono di generare rapidamente fixture JSON senza librerie di terze parti, accelerando lo sviluppo e la prototipazione.

swift
import Foundation

// Struttura di base dell'utilizzo di 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("Errore di analisi JSON: \(error)")
}

Metodi principali della classe

JSONSerialization fornisce quattro metodi principali per lavorare con JSON. Il metodo principale è jsonObject(with:options:), che converte Data in oggetti Foundation. Il metodo data(withJSONObject:options:) esegue la serializzazione inversa. isValidJSONObject(_:) verifica se un oggetto può essere serializzato. writeJSONObject(_:to:options:error:) scrive JSON direttamente in un flusso. Per leggere JSON da InputStream, esiste il metodo jsonObject(with:options:) che accetta un flusso invece di Data, comodo quando ci si integra con richieste di rete che restituiscono dati in streaming.

JSONObject e JSONData

Il metodo jsonObject accetta Data e restituisce Any — generalmente NSDictionary o NSArray. Per un uso sicuro, il risultato viene convertito nel tipo previsto tramite casting condizionale. Il metodo data accetta un oggetto Foundation e restituisce Data con una rappresentazione JSON. L'opzione .prettyPrinted aggiunge la formattazione con indentazione per la leggibilità.

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

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

Esempi di analisi JSON

Analisi di base di un dizionario con tipi primitivi è l'operazione più comune con JSONSerialization. Dopo aver ricevuto Data tramite URLSession, lo sviluppatore chiama jsonObject e converte il risultato nel tipo previsto. Per array di oggetti, si utilizza il casting a [[String: Any]], dopo di che ogni elemento viene elaborato in un ciclo. Questo approccio è flessibile ma richiede la gestione manuale dei tipi.

Analisi di strutture annidate

Le API reali restituiscono oggetti JSON annidati complessi con array, date e campi opzionali. JSONSerialization gestisce correttamente qualsiasi profondità di annidamento, ma lo sviluppatore deve convertire ogni livello al tipo richiesto in modo indipendente. Per semplificare questo compito, Apple raccomanda di utilizzare Codable per i dati tipizzati e JSONSerialization solo per le strutture dinamiche.

swift
// Analisi della risposta 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("Utente: \(name) (ID: \(userId))")

    } catch let error as ParsingError {
        print("Analisi fallita: \(error)")
    } catch {
        print("Errore imprevisto: \(error)")
    }
}

enum ParsingError: Error {
    case missingField
    case invalidType
}

Gestione degli errori

JSONSerialization genera errori in caso di JSON non valido, mancata corrispondenza dei tipi o superamento della profondità di annidamento. Gli errori appartengono al tipo CocoaError e contengono un codice che descrive il problema. Lo sviluppatore deve gestirli tramite una costruzione do-catch, altrimenti l'applicazione si bloccherà. Gli errori più comuni sono: NSPropertyListReadCorruptError (JSON non valido) e NSPropertyListReadUnknownError. Ogni tipo di errore richiede la propria strategia di gestione: per formato non valido, richiedere il reinvio dei dati e, per mancata corrispondenza della struttura, aggiornare il modello di analisi.

Tipi di errori di deserializzazione

JSON non valido — la causa più comune di fallimenti: una virgola mancante, un carattere extra o una virgoletta non escapata rompe l'intera analisi. Il secondo tipo di errore è la mancata corrispondenza con la struttura prevista: ad esempio, il server ha restituito un array invece di un dizionario. JSONSerialization.fragmentsAllowed consente di leggere JSON la cui radice non è un dizionario o un array ma un valore primitivo. Lo sviluppatore può anche incontrare un errore di superamento della profondità di annidamento quando JSON contiene troppi livelli gerarchici.

Opzioni di lettura e scrittura

JSONSerialization fornisce diverse opzioni per configurare l'analisi. .mutableContainers restituisce NSMutableDictionary e NSMutableArray invece delle versioni immutabili, utile quando si modificano i dati dopo l'analisi. .mutableLeaves rende mutabili i valori stringa. .fragmentsAllowed consente JSON la cui radice non è un oggetto o array ma una stringa o numero — comodo per risposte API semplici. Le opzioni .withoutEscapingSlashes e .sortedKeys sono disponibili per il metodo data(withJSONObject:options:), controllando la formattazione del JSON serializzato. Le opzioni vengono passate come maschera di bit, consentendo di combinare più valori tramite l'operatore | per una configurazione flessibile dell'analisi.

swift
// Gestione di vari tipi di errori
func safeParse(jsonData: Data) {
    do {
        let object = try JSONSerialization
            .jsonObject(with: jsonData,
                           options: .fragmentsAllowed)

        if let dictionary = object as? [String: Any] {
            print("Dizionario con \(dictionary.count) chiavi")
        } else if let array = object as? [Any] {
            print("Array con \(array.count) elementi")
        }

    } catch CocoaError.propertyListReadCorrupt {
        print("Dati JSON corrotti")
    } catch let error as CocoaError {
        print("Errore Cocoa: \(error)")
    } catch {
        print("Errore sconosciuto: \(error)")
    }
}

// Verifica della validità dell'oggetto prima della serializzazione
let testObject: [String: Any] = ["key": "value", "nested": ["a": 1]]
if JSONSerialization.isValidJSONObject(testObject) {
    print("Oggetto JSON valido")
}

Le prestazioni di JSONSerialization dipendono dalla dimensione dei dati e dalla frequenza delle chiamate. Per una singola analisi di una piccola risposta del server, la differenza è trascurabile, ma quando si elaborano decine di megabyte di JSON o chiamate frequenti in cicli, l'overhead del casting dei tipi deve essere considerato. JSONSerialization funziona in modo sincrono nel thread corrente, quindi per documenti grandi si consiglia di spostare l'analisi in una coda in background tramite DispatchQueue.global(). In alternativa, è possibile utilizzare InputStream per l'elaborazione in streaming senza caricare l'intero file in memoria, il che è fondamentale per applicazioni con risorse limitate. Per scrivere JSON in un file o flusso di rete, il metodo writeJSONObject(_:to:options:error:) consente di inviare direttamente dati serializzati a OutputStream senza creare un oggetto Data intermedio, riducendo il consumo di memoria quando si lavora con documenti grandi.

Domande frequenti

Cos'è JSONSerialization in iOS?

JSONSerialization è una classe Foundation per convertire Data JSON in oggetti Foundation (NSDictionary, NSArray) e viceversa. Funziona su iOS, macOS, tvOS e watchOS senza librerie aggiuntive.

In cosa differisce JSONSerialization da Codable?

Codable è un protocollo Swift per la serializzazione tipizzata automatica che si compila in codice type-safe. JSONSerialization lavora con tipi dinamici Any e richiede casting manuale. Codable è preferibile per nuovi progetti, JSONSerialization per Objective-C e dati dinamici.

Come gestire un errore di analisi JSON?

Utilizzare la costruzione do-catch quando si chiama jsonObject. Gli errori di JSONSerialization appartengono a CocoaError. Per il debug, controllare NSPropertyListReadCorruptError, che indica un formato dati JSON non valido.

JSONSerialization supporta strutture annidate?

Sì, JSONSerialization supporta qualsiasi profondità di annidamento di dizionari e array. Tutti gli oggetti annidati vengono convertiti nei corrispondenti tipi Foundation (NSDictionary, NSArray, NSString, NSNumber), preservando la struttura JSON originale.

Quando utilizzare JSONSerialization invece di Codable?

JSONSerialization è appropriato per strutture JSON dinamiche, in progetti Objective-C, quando si lavora con flussi e per la validazione JSON tramite isValidJSONObject. Per strutture tipizzate con uno schema noto, Codable è preferibile.

Riepilogo

  • JSONSerialization — una classe Foundation integrata per la gestione di base di JSON sulle piattaforme Apple
  • jsonObject — il metodo principale di analisi che converte Data in dizionari e array Foundation
  • data — metodo di serializzazione inversa di oggetti Foundation in Data JSON con opzioni di formattazione
  • isValidJSONObject — un predicato per verificare se un oggetto può essere serializzato in JSON
  • Gestione degli errori è obbligatoria tramite do-catch per prevenire il blocco dell'applicazione
  • Codable — un'alternativa tipizzata moderna per progetti Swift con uno schema dati noto

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche