currently I'm trying to decode JSON with a nested Array. The nested array can have some random numbers of the object inside it. I try to decode it but turns out it return an errors
CodingKeys(stringValue: "itenaries", intValue: nil),
debugDescription : "Expected to decode Array<Any> but found a dictionary
Sample JSON data
{
"itenaries": {
"days":
[
[
{
"itenary_id":0,
"itenary_location_name":"Batu Caves Temple"
}
],
[
{
"itenary_id":0,
"itenary_location_name":"KL Tower "
},
{
"itenary_id":1,
"itenary_location_name":"KL Forest Eco Park"
}
]
]
}
}
My Struct
struct Itenaries : Codable {
let itenaries : [[Days]]
}
struct Days : Codable {
let itenary_id : Int
let itenary_location_name : String
}
Decoding Implementation
let decoder = JSONDecoder()
let itenary = try decoder.decode(Itenaries.self, from: fileData)
print(itenary.itenaries[0][0].itenary_id)
Where do you decode the days
key? That's the problem. You need an intermediate struct
struct Root : Decodable {
let itenaries : Itenary
}
struct Itenary : Decodable {
let days : [[Days]]
}
...
let result = try decoder.decode(Root.self, from: fileData)
print(result.iternaries.days[0][0].itenary_id)
i'd probably do something like
struct Name:Codable {
var itenaries:itenaries
}
struct itenaries:Codable {
var days = [[Days]]
}
struct Days : Codable {
let itenary_id : Int
let itenary_location_name : String
}
so basically according the structure of your Json file Root struct -> itenaries -> [[days]]
hope you understand:)
[Edited] you can try these. I'm getting correct result using this approach
struct MainResponse : Codable {
let itenaries : Itenaries
}
struct Itenaries : Codable {
let days : [[Days]]
}
struct Days : Codable {
let itenary_id : Int
let itenary_location_name : String
}
if let path = Bundle.main.path(forResource: "nested_array", ofType: "json") {
do {
let responseData = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let decoder = JSONDecoder()
let mainResponse = try decoder.decode(MainResponse.self, from: responseData)
print(mainResponse.itenaries.days[0][0].itenary_id)
print(mainResponse.itenaries.days[0][0].itenary_location_name)
print(mainResponse.itenaries.days[1][0].itenary_id)
print(mainResponse.itenaries.days[1][0].itenary_location_name)
print(mainResponse.itenaries.days[1][1].itenary_id)
print(mainResponse.itenaries.days[1][1].itenary_location_name)
// output
// 0
// Batu Caves Temple
// 0
// KL Tower
// 1
// KL Forest Eco Park
} catch let error {
print(error.localizedDescription)
}
}
Your model is not correct, replace it by the following:
struct ItenariesResponse: Codable {
let itenaries: Itenaries
}
struct Itenaries: Codable {
let days: [[Day]]
}
struct Day: Codable {
let itenaryID: Int
let itenaryLocationName: String
enum CodingKeys: String, CodingKey {
case itenaryID = "itenary_id"
case itenaryLocationName = "itenary_location_name"
}
}
Then replace the type you decode like that:
let itenary = try decoder.decode(ItenariesResponse.self, from: fileData)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.