JSONSerialization — une classe iOS intégrée du framework Foundation conçue pour convertir du JSON en objets Foundation et vice versa. Cette API est le mécanisme de base pour travailler avec JSON sur les plateformes Apple sans bibliothèques tierces, prenant en charge l’analyse de dictionnaires, tableaux et types primitifs. Selon Apple Developer, 2024, JSONSerialization prend en charge le travail avec Data, les flux et les options de lecture pour un traitement flexible des données JSON.
Points clés
JSONSerialization est une classe du framework Foundation disponible sur iOS, macOS, tvOS et watchOS. Elle fournit des méthodes pour convertir Data JSON en objets Foundation (NSDictionary, NSArray, NSString, NSNumber) et vice versa. La classe est apparue dans iOS 5 et jusqu’à l’introduction de Codable (Swift 4) est restée le principal moyen de travailler avec JSON sur les plateformes Apple. Malgré son âge, JSONSerialization reste pertinent dans les projets legacy en Objective-C et dans les scénarios nécessitant un traitement JSON dynamique sans schéma de modèle fixe.
Malgré l’avènement de Codable, JSONSerialization reste pertinent dans plusieurs scénarios. Structure JSON dynamique — lorsque le format de réponse change ou est inconnu à l’avance — nécessite l’accès aux dictionnaires par clés, ce qui est plus facile à faire via JSONSerialization. La classe est également utilisée dans les projets Objective-C où Codable n’est pas disponible, et lors du travail avec des flux pour l’analyse incrémentielle de gros fichiers JSON. Dans les tests et maquettes, isValidJSONObject et data(withJSONObject:options:) permettent de générer rapidement des fixtures JSON sans bibliothèques tierces, accélérant le développement et le prototypage.
import Foundation
// Structure de base d’utilisation de 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("Erreur d’analyse JSON : \(error)")
}
JSONSerialization fournit quatre méthodes principales pour travailler avec JSON. La méthode principale est jsonObject(with:options:), qui convertit Data en objets Foundation. La méthode data(withJSONObject:options:) effectue la sérialisation inverse. isValidJSONObject(_:) vérifie si un objet peut être sérialisé. writeJSONObject(_:to:options:error:) écrit JSON directement dans un flux. Pour lire JSON depuis InputStream, il existe la méthode jsonObject(with:options:) qui accepte un flux au lieu de Data, ce qui est pratique lors de l’intégration avec des requêtes réseau renvoyant des données en streaming.
La méthode jsonObject accepte Data et retourne Any — généralement NSDictionary ou NSArray. Pour une utilisation sécurisée, le résultat est converti au type attendu par conversion conditionnelle. La méthode data accepte un objet Foundation et retourne Data avec une représentation JSON. L’option .prettyPrinted ajoute un formatage avec indentation pour la lisibilité.
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("Produit : \(name)")
}
}
}
// Sérialisation inverse : objet -> JSON
let outputDict: [String: Any] = ["status": "ok", "count": 42]
if let outputData = try? JSONSerialization
.data(withJSONObject: outputDict,
options: .prettyPrinted) {
String(data: outputData, encoding: .utf8)
}
Analyse de base d’un dictionnaire avec des types primitifs est l’opération la plus courante avec JSONSerialization. Après avoir reçu Data via URLSession, le développeur appelle jsonObject et convertit le résultat au type attendu. Pour les tableaux d’objets, on utilise la conversion vers [[String: Any]], puis chaque élément est traité dans une boucle. Cette approche est flexible mais nécessite une gestion manuelle des types.
Les API réelles retournent des objets JSON imbriqués complexes avec des tableaux, des dates et des champs optionnels. JSONSerialization gère correctement toute profondeur d’imbrication, mais le développeur doit convertir chaque niveau au type requis de manière indépendante. Pour simplifier cette tâche, Apple recommande d’utiliser Codable pour les données typées et JSONSerialization uniquement pour les structures dynamiques.
// Analyse de réponse 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("Utilisateur : \(name) (ID : \(userId))")
} catch let error as ParsingError {
print("Échec d’analyse : \(error)")
} catch {
print("Erreur inattendue : \(error)")
}
}
enum ParsingError: Error {
case missingField
case invalidType
}
JSONSerialization lance des erreurs en cas de JSON invalide, d’incompatibilité de types ou de dépassement de profondeur d’imbrication. Les erreurs appartiennent au type CocoaError et contiennent un code décrivant le problème. Le développeur doit les gérer via une construction do-catch, sinon l’application plantera. Les erreurs les plus courantes sont : NSPropertyListReadCorruptError (JSON invalide) et NSPropertyListReadUnknownError. Chaque type d’erreur nécessite sa propre stratégie de gestion : pour un format invalide, demander un renvoi des données, et pour une incompatibilité de structure, mettre à jour le modèle d’analyse.
JSON invalide — la cause la plus fréquente d’échecs : une virgule manquante, un caractère supplémentaire ou un guillemet non échappé casse toute l’analyse. Le deuxième type d’erreurs est l’incompatibilité avec la structure attendue : par exemple, le serveur a renvoyé un tableau au lieu d’un dictionnaire. JSONSerialization.fragmentsAllowed permet de lire JSON dont la racine n’est pas un dictionnaire ou un tableau mais une valeur primitive. Le développeur peut également rencontrer une erreur de profondeur d’imbrication dépassée lorsque JSON contient trop de niveaux hiérarchiques.
JSONSerialization fournit plusieurs options pour configurer l’analyse. .mutableContainers retourne NSMutableDictionary et NSMutableArray au lieu des versions immuables, ce qui est utile lors de la modification des données après l’analyse. .mutableLeaves rend les valeurs chaîne modifiables. .fragmentsAllowed permet JSON dont la racine n’est pas un objet ou un tableau mais une chaîne ou un nombre — pratique pour les réponses API simples. Les options .withoutEscapingSlashes et .sortedKeys sont disponibles pour la méthode data(withJSONObject:options:), contrôlant le formatage du JSON sérialisé. Les options sont passées sous forme de masque de bits, permettant de combiner plusieurs valeurs via l’opérateur | pour une configuration flexible de l’analyse.
// Gestion de divers types d’erreurs
func safeParse(jsonData: Data) {
do {
let object = try JSONSerialization
.jsonObject(with: jsonData,
options: .fragmentsAllowed)
if let dictionary = object as? [String: Any] {
print("Dictionnaire avec \(dictionary.count) clés")
} else if let array = object as? [Any] {
print("Tableau avec \(array.count) éléments")
}
} catch CocoaError.propertyListReadCorrupt {
print("Données JSON corrompues")
} catch let error as CocoaError {
print("Erreur Cocoa : \(error)")
} catch {
print("Erreur inconnue : \(error)")
}
}
// Vérification de validité de l’objet avant sérialisation
let testObject: [String: Any] = ["key": "value", "nested": ["a": 1]]
if JSONSerialization.isValidJSONObject(testObject) {
print("Objet JSON valide")
}
Les performances de JSONSerialization dépendent de la taille des données et de la fréquence des appels. Pour une seule analyse d’une petite réponse serveur, la différence est négligeable, mais lors du traitement de dizaines de mégaoctets de JSON ou d’appels fréquents dans des boucles, la surcharge de la conversion de type doit être prise en compte. JSONSerialization fonctionne de manière synchrone dans le thread actuel, donc pour les grands documents, il est recommandé de déplacer l’analyse vers une file d’attente en arrière-plan via DispatchQueue.global(). Alternativement, vous pouvez utiliser InputStream pour un traitement en streaming sans charger l’intégralité du fichier en mémoire, ce qui est crucial pour les applications aux ressources limitées. Pour écrire JSON dans un fichier ou un flux réseau, la méthode writeJSONObject(_:to:options:error:) permet d’envoyer directement les données sérialisées vers OutputStream sans créer d’objet Data intermédiaire, réduisant la consommation mémoire lors du travail avec de grands documents.
Foire aux questions
JSONSerialization est une classe Foundation pour convertir Data JSON en objets Foundation (NSDictionary, NSArray) et vice versa. Elle fonctionne sur iOS, macOS, tvOS et watchOS sans bibliothèques supplémentaires.
Codable est un protocole Swift pour la sérialisation typée automatique qui se compile en code type-safe. JSONSerialization fonctionne avec des types dynamiques Any et nécessite un casting manuel. Codable est préférable pour les nouveaux projets, JSONSerialization pour Objective-C et les données dynamiques.
Utilisez la construction do-catch lors de l’appel de jsonObject. Les erreurs JSONSerialization appartiennent à CocoaError. Pour le débogage, vérifiez NSPropertyListReadCorruptError, qui indique un format de données JSON invalide.
Oui, JSONSerialization prend en charge toute profondeur d’imbrication de dictionnaires et de tableaux. Tous les objets imbriqués sont convertis dans les types Foundation correspondants (NSDictionary, NSArray, NSString, NSNumber), préservant la structure JSON d’origine.
JSONSerialization est approprié pour les structures JSON dynamiques, dans les projets Objective-C, lors du travail avec des flux et pour la validation JSON via isValidJSONObject. Pour les structures typées avec un schéma connu, Codable est préférable.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi