web-dev-qa-db-fra.com

Swift 4 Codable décodage json

J'essaie d'implémenter le nouveau protocole Codable, alors j'ai ajouté Codable à ma structure, mais je suis {bloqué sur le décodage du JSON} _.

Voici ce que j'avais auparavant:

Struct -

struct Question {
    var title: String
    var answer: Int
    var question: Int
}

Client -

...

guard let data = data else {
    return
}

do {
    self.jsonResponse = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any]
    let questionItems = self.jsonResponse?["themes"] as! [[String: Any]]

    questionItems.forEach {
        let item = Question(title: $0["title"] as! String,
                            answer: $0["answer"] as! Int,
                            question: $0["question"] as! Int)
        questionData.append(item)
    }

} catch {
    print("error")
}

Voici ce que j'ai maintenant, sauf que je ne peux pas comprendre la partie décodeur:

Struct - 

struct Question: Codable {
    var title: String
    var answer: Int
    var question: Int
}

Client - 

...

let decoder = JSONDecoder()
if let questions = try? decoder.decode([Question].self, from: data) {
    // Can't get past this part
} else {
    print("Not working")
}

Il affiche "Ne fonctionne pas" car je ne peux pas dépasser la partie decoder.decode. Des idées? Publiera tout code supplémentaire au besoin, merci!

MODIFIER:

Exemple d'API JSON: 

{
  "themes": [
    {
      "answer": 1,
      "question": 44438222,
      "title": "How many letters are in the alphabet?"
    },
    {
      "answer": 0,
      "question": 44438489,
      "title": "This is a random question"
    }
  ]
 }

Si j'imprime self.jsonResponse j'obtiens ceci:

Optional(["themes": <__NSArrayI 0x6180002478f0>(
{
    "answer" = 7;
    "question" = 7674790;
    title = "This is the title of the question";
},
{
    "answer_" = 2;
    "question" = 23915741;
    title = "This is the title of the question";
}

Mon nouveau code:

struct Theme: Codable {
    var themes : [Question]
}

struct Question: Codable {
    var title: String
    var answer: Int
    var question: Int
}

...

if let decoded = try? JSONDecoder().decode(Theme.self, from: data) {
    print("decoded:", decoded)
} else {
    print("Not working")
}
7
SRMR

Si votre JSON a une structure

{"themes" : [{"title": "Foo", "answer": 1, "question": 2},
             {"title": "Bar", "answer": 3, "question": 4}]}

vous avez besoin d'un équivalent pour l'objet themes. Ajouter cette structure

struct Theme : Codable {
    var themes : [Question]
}

Maintenant, vous pouvez décoder le JSON:

if let decoded = try? JSONDecoder().decode(Theme.self, from: data) {
    print("decoded:", decoded)
} else {
    print("Not working")
}

Les objets contenant la variable Question sont décodés implicitement.

8
vadian

Vous obtenez cette erreur car votre JSON est probablement structuré de la manière suivante:

{
  "themes": [
    { "title": ..., "question": ..., "answer": ... },
    { "title": ..., "question": ..., "answer": ... },
    { ... }
  ],
  ...
}

Cependant, le code que vous avez écrit attend un [Question] au plus haut niveau. Ce dont vous avez besoin est un type de niveau supérieur différent qui possède une propriété themes qui est un [Question]. Lorsque vous décodez ce type de niveau supérieur, votre [Question] sera décodé pour la clé themes.

1
Itai Ferber

Bonjour @all, j'ai ajouté le code pour l'encodage et le décodage JSON pour Swift 4.

Veuillez utiliser le lien ici

0
CrazyPro007