I'm encountering a fatal error when trying to decode a JSON file into my custom Swift struct AnimalGroup. The error occurs when decoding the file classification.json, and it specifically complains about a missing "id" key even though the "id" key is present in the JSON.
Fatal error: Couldn't parse classification.json as AnimalGroup:
keyNotFound(CodingKeys(stringValue: "id", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"id\", intValue: nil) (\"id\").", underlyingError: nil))
Here is my AnimalGroup struct:
struct AnimalGroup: Identifiable, Decodable, Hashable {
let id: Int
let code: Int
let form: String?
let name: String
let shortName: String
func hash(into hasher: inout Hasher) {
hasher.combine(id)
hasher.combine(name)
}
}
This is how I load JSON data and return the decoded data:
var previewAnimal: Animal = load("animal.json")
var previewGroup: AnimalGroup = load("classification.json")
// Function that loads JSON data into a T type and returns the decoded data
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase // Remember to add this line to avoid running into a crash
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
Here is a sample of my classification.json file:
{
"group": [
{
"code": 3,
"form": null,
"id": 1,
"name": "Vertebrates",
"short_name": "CRS",
},
{
"code": 4,
"form": null,
"id": 2,
"name": "Mammal",
"short_name": "CRS",
},
{
"code": 5,
"form": null,
"id": 3,
"name": "Reptile",
"short_name": "CRS",
},
{
"code": 6,
"form": null,
"id": 4,
"name": "Avians",
"short_name": "CRS",
},
{
"code": 7,
"form": null,
"id": 5,
"name": "Amphibians",
"short_name": "CRS",
}
]
}
My question: How can I handle the situation where a key like "id" is not missing from the JSON but Xcode is saying it's missing?
I used the Decodable protocol to decode my JSON into the AnimalGroup struct. The JSON includes the id field, so I expected the decoding to work. However, despite the id being present in the JSON, I'm still getting the keyNotFound error during decoding.
I was expecting the decoder to map the id key from the JSON to the AnimalGroup struct without any issues, but it results in a fatal error instead.
Your struct handles the fields of a single animal. Your JSON contains a dictionary with the key "group". The value for that key is an array of your AnimalGroup
structs.
You need an outer object that hosts an array of AnimalGroup
objects ("AnimalGroupGroup"?)