Vous trouverez ci-dessous ma réponse json et la structure que je dois en extraire.
condition: je ne voudrais pas créer une autre structure en dehors de Response, Media et je voudrais analyser en une seule ligne comme spécifié ci-dessous .
{ "name": "xxxx", "title": "xxxxxxx", "assets": [ { "items": [ { "id": "eeee", "desc": "rrrrrr" }, { "id": "eeee", }, { "desc": "rrrrrr" }] }] } struct Response { let name : String let title : string let items : [Media] private enum codingKeys : String, CodingKey { case name = "name" case title = "title" case items = "assets.items" } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: codingKeys.self) name = try container.decode(String.self, forKey: .name) title = try container.decode(TrayLayout.self, forKey: .title) items = try container.decode([Media].self, forKey: .items) } }
3 Réponses :
Vous pouvez essayer ceci:
guard let response = try? JSONDecoder().decode(Response.self, from: data) else { print("Response not parsed"); return }
Ensuite, vous pouvez simplement le décoder comme ceci:
struct Response: Decodable { let name, title: String let assets: [Assets] } struct Assets: Decodable { let items: [Items] } struct Items: Decodable { let id, desc: String }
Hey rob, je ne voudrais pas créer de nouvelles structures d'actifs
J'ai réussi à trouver une solution à votre problème.
Considérant que l'exemple suivant est json
myResponse.name myResponse.title myResponse.items
Vos structures ressembleront à celles ci-dessous
let data = jsonString.data(using: .utf8)! let myResponse = try! JSONDecoder().decode(Response.self, from: data)
À la fin, il est temps de l'utiliser comme suit
struct Media: Codable { let id,desc: String? enum CodingKeys: String, CodingKey { case id,desc } } struct Response: Decodable { let name,title: String? let items: [Media]? enum CodingKeys: String, CodingKey { case name,title,items case assets = "assets" } // Decoding init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) name = try container.decode(String.self, forKey: .name) title = try container.decode(String.self, forKey: .title) // Here as the assets contains array of object which has a key as items and then again consist of a array of Media we need to decode as below let assets = try container.decode([[String:[Media]]].self, forKey: .assets) // At this stage will get assets with a array of array so we first map and retrive the items and then reduce them to one single array items = assets.compactMap{$0[CodingKeys.items.rawValue]}.reduce([], +) } }
Vous pouvez maintenant accéder aux données comme ci-dessous
let jsonString = """ { "name": "xxxx", "title": "xxxxxxx", "assets": [ { "items": [ { "id": "id11", "desc": "desc11" }, { "id": "id12", }, { "desc": "desc13" }] },{ "items": [ { "id": "id21", "desc": "desc21" }, { "id": "id22", }, { "desc": "desc23" }] }] } """
Nous avons trouvé un nouveau moyen:
struct Media: Codable { let id,desc: String? enum CodingKeys: String, CodingKey { case id,desc } } struct Response: Decodable, CustomStringConvertible { let name,title: String? @NestedKey let items: [Media]? enum CodingKeys: String,NestableCodingKey { case name,title, case items = "assets/items" } }
Veuillez jeter un oeil à la réponse suivante et voir si cela vous aide à atteindre votre objectif.