I am using below code to parse json from API
struct ResourceInfo: Decodable {
let id: String
let type: String
// let department: String. -> Unable to get the value for department
}
struct CustomerInfo: Decodable {
let name: String
let country: String
let resources: [ResourceInfo]
enum CodingKeys: CodingKey {
case name
case country
case resources
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decode(String.self, forKey: .name)
self.country = try container.decode(String.self, forKey: .country)
let resourcesDict = try container.decode([String: ResourceInfo].self, forKey: .resources)
//print(resourcesDict.map { $0.key })
self.resources = resourcesDict.map { $0.value }
}
}
static func parseJson() {
let json = """
{
"name": "John",
"country": "USA",
"resources": {
"electronics": {
"id": "101",
"type": "PC"
},
"mechanical": {
"id": "201",
"type": "CAR"
},
"science": {
"id": "301",
"type": "CHEM"
}
}
}
"""
let result = try? JSONDecoder().decode(CustomerInfo.self, from: json.data(using: .utf8)!)
dump(result)
}
Output:
Optional(JsonSample.CustomerInfo(name: "John", country: "USA", resources: [JsonSample.ResourceInfo(id: "201", type: "CAR"), JsonSample.ResourceInfo(id: "301", type: "CHEM"), JsonSample.ResourceInfo(id: "101", type: "PC")]))
▿ some: JsonSample.CustomerInfo
- name: "John"
- country: "USA"
▿ resources: 3 elements
▿ JsonSample.ResourceInfo
- id: "201"
- type: "CAR"
▿ JsonSample.ResourceInfo
- id: "301"
- type: "CHEM"
▿ JsonSample.ResourceInfo
- id: "101"
- type: "PC"
Could someone help me get the value department like electronics
, mechanical
& science
? Thank you
3
Answers
You throw away the information in the line
resourcesDict.map { $0.value }
because you ignore thekeys
.My suggestion is to add a temporary helper struct, decode that and map the dictionary to
ResourceInfo
with bothkey
andvalue
You could try this approach, where you decode
ResourceInfo
initially with just its CodingKeys,then remap the results with the dictionary keys as the
department
,as shown in the SwiftUI example code:
The difficulty lies in the fact that the data structure you want doesn’t map directly with the hierarchy in the JSON. The department name is a key to a dictionary containing the id and type values. If you want to collapse that information into a single struct then this is one solution. There may be smarter ways to do this. I just added a separate structure for decoding the id and type: