Logo de Swift en orange sur fond gris qui sert de hero de présentation de la formation sur les fondamentaux de Swift

Codable et JSON

Logo de Swift en orange sur fond gris qui sert de hero de présentation de la formation sur les fondamentaux de Swift

Codable et JSON

Dans ce cours, on va découvrir le format JSON pour JavaScript Object Notation. C’est un format de données qui est très répandu dans le monde du développement. Le JSON est souvent utilisé pour transmettre et recevoir des données entre un serveur et une application.

Comment ça fonctionne ? Pour faire simple, des données sous format JSON sont stockées sur un serveur. Moi, avec mon application, je vais faire une requête vers ce serveur afin de récupérer les données du JSON dans mon programme. Une fois que j’ai réussi à récupérer les données JSON, je vais devoir traduire les données du format JSON en un format de données que je pourrai lire dans mon programme en Swift, un objet par exemple. Je t’explique en détail les bases du JSON et comment on va traduire ces données dans notre programme :

Structure du JSON

Un fichier JSON est composé de paires clé-valeur et de listes de valeurs. Je te présente les composants de base.

Types de données JSON


Number (ex : 10, 3.14)

String (ex : "Salut")

Bool (ex : true, false)

Array (ex : ["Pomme", "Mangue", "Fraise"])

Object (ex : {"prenom": "Sarah", "nom": "Connor"})

null
Tu retrouves dans le format JSON sensiblement les mêmes types de données qu’en Swift.

Syntaxe


{
    "name": "Harry Potter",
    "age": 20,
    "isWizard": true
}
Les valeurs d’un JSON sont stockées dans des accolades {}.

 

Tableau


[
    "Harry Potter",
    "Hermione Granger",
    "Ron Weasley"
]

Comme en Swift, les valeurs sont entourées de crochets [].

Objet


{
    "House": "Griffondor",
    "students": [
        { "name": "Harry Potter", "age": 20 },
        { "name": "Hermione Granger", "age": 20 },
        { "name": "Ron Weasley", "age": 20 }
    ]
}
On considère souvent les données JSON comme un objet. En effet, si on observe bien ici, on a une structure de données comme on pourrait en avoir en Swift sous forme d’objet.

Lire des Données JSON en Swift avec le Protocole Codable

Le protocole Codable nous permet de lire (décoder) des données JSON en objets Swift et de transformer (encoder) des objets Swift en données JSON. C’est une manière simple de gérer les données JSON.

Définir les Structures

Pour utiliser le protocole Codable, je vais définir des structures qui correspondent à la structure du JSON. Chaque clé du JSON doit avoir une propriété correspondante dans notre structure. Par exemple :

 

JSON


{
    "name": "Harry Potter",
    "age": 20,
    "isWizard": true
}

Structure correspondante


struct Student: Codable {
    var name: String
    var age: Int
    var isWizard: Bool
}

Ici, Student adopte le protocole Codable. Ça signifie que cette structure peut être encodée et décodée à partir du JSON.

Décoder les données JSON

J’ai volontairement créé une constante comprenant du JSON jsonData. Normalement, tu chargerais ton JSON depuis une URL ou un fichier.



let jsonData = """
{
    "name": "Harry Potter",
    "age": 20,
    "isWizard": true
}
""".data(using: .utf8)!

do {
    let student = try JSONDecoder().decode(Student.self, from: jsonData)
    print("Nom: \(student.name), Âge: \(student.age), Est Sorcier: \(student.isWizard)")
} catch {
    print("Erreur de décodage: \(error)")
}
Ici notre objectif est d’enfin décoder notre JSON en objet Swift, c’est ici que ça ce passe.

C’est une opération qui à un risque d’erreur (nous n’avons pas toujours le contrôle sur les données d’un JSON vu que ce sont souvent des données externes à nos programmes)

Une bonne pratique est d’utiliser un bloc do try catch pour rappel do va lancer le bloc de code, try va lancer le code qui peut générer une erreur et catch va capturer l’erreur si il y a.

Intéressons nous maintenant à notre JSONDecoder, qui est une classe fournit par swift pour décoder des données JSON en instance d’objet. Pour utiliser JSONDecoder les types que l’on souhaite convertir doivent être conforme au protocole Codable (comme nous l’avons déjà paramétrer sur notre struct Student)

JSONDecoder.().decode(Student.self, from: data) dans notre exemple on utilise la méthode .decode qui demande a JSONDecoder de convertir les données du JSON contenu dans data en une instance du type Student. Si le décodage réussit, student devient une instance de Student remplie avec les données extraites du JSON.

On peut enfin afficher notre titre dans la console print("Nom: \\(student.name), Âge: \\(student.age), Est Sorcier: \\(student.isWizard)")

  Décoder un tableau JSON



let jsonArrayData = """
[
    {
        "name": "Harry Potter",
        "age": 20,
        "isWizard": true
    },
    {
        "name": "Hermione Granger",
        "age": 20,
        "isWizard": true
    },
    {
        "name": "Ron Weasley",
        "age": 20,
        "isWizard": true
    }
]
""".data(using: .utf8)!

do {
    let students = try JSONDecoder().decode([Student].self, from: jsonArrayData)
    for student in students {
        print("Nom: \(student.name), Âge: \(student.age), Est Sorcier: \(student.isWizard)")
    }
} catch {
    print("Erreur de décodage: \(error)")
}

}
Pour le coup, rien de bien nouveau pour nous. On va simplement boucler sur students pour afficher chaque valeur récupérée.

 Décoder un Objet


{
    "House": "Griffondor",
    "students": [
        { "name": "Harry Potter", "age": 20 },
        { "name": "Hermione Granger", "age": 20 },
        { "name": "Ron Weasley", "age": 20 }
    ]
}

Cette fois, on va décoder un objet JSON. C’est là qu’il faut prendre le temps d’analyser comment est fait l’objet à traduire pour bien le faire correspondre à notre programme. Ici, on peut observer deux valeurs distinctes : House pour représenter une maison, et students qui représentent les élèves affiliés à cette maison. La bonne pratique serait de créer deux structures indépendantes pour les représenter dans notre code.


struct Student: Codable {
    var name: String
    var age: Int
}

struct House: Codable {
    var House: String
    var students: [Student]
}

Un objet seul



let jsonData = """
{
    "House": "Griffondor",
    "students": [
        { "name": "Harry Potter", "age": 20 },
        { "name": "Hermione Granger", "age": 20 },
        { "name": "Ron Weasley", "age": 20 }
    ]
}
""".data(using: .utf8)!


do {
    let griffondor = try JSONDecoder().decode(House.self, from: jsonData)
    print("Maison: \(griffondor.House)")
    for student in griffondor.students {
        print("Nom: \(student.name), Âge: \(student.age)")
    }
} catch {
    print("Erreur de décodage: \(error)")
}

Un tableau d’objet


let jsonData = """
[
    {
        "House": "Griffondor",
        "students": [
            { "name": "Harry Potter", "age": 20 },
            { "name": "Hermione Granger", "age": 20 },
            { "name": "Ron Weasley", "age": 20 }
        ]
    },
    {
        "House": "Serpentard",
        "students": [
            { "name": "Draco Malfoy", "age": 20 },
            { "name": "Pansy Parkinson", "age": 20 },
            { "name": "Gregory Goyle", "age": 20 }
        ]
    }
]
""".data(using: .utf8)!


do {
    let houses = try JSONDecoder().decode([House].self, from: jsonData)
    for house in houses {
        print("Maison: \(house.House)")
        for student in house.students {
            print("Nom: \(student.name), Âge: \(student.age)")
        }
        print("-----")
    }
} catch {
    print("Erreur de décodage: \(error)")
}

Encoder



struct Student: Codable {
    var name: String
    var age: Int
    var isWizard: Bool
}

let harry = Student(name: "Harry Potter", age: 20, isWizard: true)

do {
    let jsonData = try JSONEncoder().encode(harry)
    if let jsonString = String(data: jsonData, encoding: .utf8) {
        print("JSON String : \(jsonString)")
    }
} catch {
    print("Erreur d'encodage : \(error)")
}

Avec le protocole Codable, nous avons vu comment décoder des données au format JSON en objet Swift. Ce protocole nous permet également d’encoder un objet Swift en JSON. Comme dans l’exemple ci-dessus, nous utilisons la méthode JSONEncoder() pour transformer harry d’un objet Swift en une donnée JSON. Cela sera particulièrement utile si tu souhaites envoyer des données de ton application vers un serveur distant traitant ces données en JSON.

Exercices Pratiques

Exo Codable et JSON

Télécharger le playground

Accède aux consignes directement en téléchargeant le playground.

⚠️ Les consignes que tu trouveras dans le playground ne sont pas verrouillées. Fais attention à ne pas les effacer par inadvertance ! 

Objectif

La gestion des données JSON est essentielle pour échanger des informations entre ton application et des services externes, comme une API. Avec le protocole Codable en Swift, tu peux convertir facilement des objets Swift en JSON (et vice-versa) de manière simple et efficace. Codable combine les protocoles Encodable et Decodable pour te permettre d’encoder et de décoder tes données sans écrire de code complexe. En maîtrisant Codable, tu pourras gérer les données de manière sécurisée, réduire les erreurs liées à la conversion de formats, et rendre ton code plus lisible et maintenable. Comprendre ces concepts te permettra de manipuler les données JSON avec confiance, un aspect clé pour créer des applications modernes et connectées.

Note

Le JSON est si populaire qu’il est devenu presque universel dans le développement moderne. Il est utilisé pour des fichiers de configuration (comme package.json ou composer.json), des bases de données NoSQL comme MongoDB, ou des APIs REST dans quasiment tous les langages de programmation.

Exercices Pratiques

Exo Codable et JSON

Télécharger le playground

Accède aux consignes directement en téléchargeant le playground.

⚠️ Les consignes que tu trouveras dans le playground ne sont pas verrouillées. Fais attention à ne pas les effacer par inadvertance ! 

Objectif

La gestion des données JSON est essentielle pour échanger des informations entre ton application et des services externes, comme une API. Avec le protocole Codable en Swift, tu peux convertir facilement des objets Swift en JSON (et vice-versa) de manière simple et efficace. Codable combine les protocoles Encodable et Decodable pour te permettre d’encoder et de décoder tes données sans écrire de code complexe. En maîtrisant Codable, tu pourras gérer les données de manière sécurisée, réduire les erreurs liées à la conversion de formats, et rendre ton code plus lisible et maintenable. Comprendre ces concepts te permettra de manipuler les données JSON avec confiance, un aspect clé pour créer des applications modernes et connectées.

Note

Le JSON est si populaire qu’il est devenu presque universel dans le développement moderne. Il est utilisé pour des fichiers de configuration (comme package.json ou composer.json), des bases de données NoSQL comme MongoDB, ou des APIs REST dans quasiment tous les langages de programmation.