2017-10-10 3 views
1

prendre la JSON suivante:décodage d'un tableau imbriqué dans rapide 4

let rawJson = 
""" 
[ 
     { 
      "id": 1, 
      "name":"John Doe" 
     }, 
     { 
      "id": 2, 
      "name":"Luke Smith" 
     }, 
] 
""" 

et User modèle:

struct User: Decodable { 
    var id: Int 
    var name: String 
} 

Il est assez simple à décoder, comme ceci:

let data = rawJson.data(using: .utf8) 
let decoder = JSONDecoder() 
let users = try! decoder.decode([User].self, from: data!) 

Mais que se passe-t-il si le JSON ressemble à ceci, où le niveau supérieur est un dictionnaire et a besoin d'aller chercher le tableau de users :

let json = 
""" 
{ 
    "users": 
    [ 
     { 
      "id": 1, 
      "name":"John Doe" 
     }, 
     { 
      "id": 2, 
      "name":"Luke Smith" 
     }, 
    ] 
} 
""" 

Quelle est la solution la plus efficace pour lire le JSON? Je pourrais certainement créer un autre struct comme ceci:

struct SomeStruct: Decodable { 
    var posts: [Post] 
} 

et décoder comme ceci:

let users = try! decoder.decode(SomeStruct.self, from: data!) 

mais il ne se sent pas bien le faire de cette façon, la création d'un nouvel objet modèle juste parce que le tableau est imbriqué dans un dictionnaire.

+1

Vérifiez cet article sous la rubrique « clés wrapper ». Il semble que c'est la bonne façon d'analyser cette structure. http://benscheirman.com/2017/06/ultimate-guide-to-json-parsing-with-swift-4/ –

Répondre

2

Si vous souhaitez tirer parti de JSONDecoder, vous devez créer une structure imbriquée (ure).

Je recommande d'utiliser le nom Root pour l'objet racine et mettre le struct enfant dans Root

struct Root : Decodable { 

    struct User : Decodable { 
     let id: Int 
     let name: String 
    } 

    let users : [User] 
} 

let json = """ 
{ 
    "users": [{"id": 1, "name":"John Doe"}, 
       {"id": 2, "name":"Luke Smith"}] 
} 
""" 

let data = Data(json.utf8) 
do { 
    let root = try JSONDecoder().decode(Root.self, from: data) 
    print(root.users) 
} catch { 
    print(error) 
} 
+0

Il n'est pas nécessaire que la structure de l'utilisateur soit imbriquée dans la structure racine 'struct User: Decodable { laisser id: Int laisser nom: struct chaîne } racine: décodables { permettent aux utilisateurs de: [utilisateur] } 'le résultat serait le même –

+1

Oui il n'y a pas besoin, mais si le struct n'est pas utilisé ailleurs c'est plus propre (imho) et il illustre l'équivalent de la structure JSON. – vadian