I have a structure as shown below:
struct ItemList: Decodable {
var items: [UUID: Int]
}
Example JSON data I get is:
{
"items": {
"b4f8d2fa-941f-4f9a-a98c-060bbd468575": 418226428193,
"81efa661-4845-491b-8bf4-06d5dff1d5f8": 417639857722
}
}
Now, when I try to decode the above data, I get an interesting error. Clearly, I'm not decoding an array and clearly everything points at a dictionary.
try JSONDecoder().decode(ItemList.self, from: data)
// typeMismatch(
// Swift.Array<Any>,
// Swift.DecodingError.Context(
// codingPath: [
// CodingKeys(stringValue: "items", intValue: nil)
// ],
// debugDescription: "Expected to decode Array<Any> but found a dictionary instead.",
// underlyingError: nil
// )
// )
So I went experimenting and changed the [UUID: Int]
to [String: Int]
, which does make this work, almost making me think the error is not array/dictionary related, but UUID/String related. So I also did the following test, which never fails.
let list = try JSONDecoder().decode(ItemList.self, from: data)
for (key, value) in list.items {
// This will never print `nil`
print(UUID(uuidString: key))
}
So my question is, why do I get this weird typeMismatch
error when decoding, and why does it work when I change the UUID
to a String
, as it can clearly be properly decoded?
this article gives a good explanation about why this happens and what you can do about it. Short summary:
a) Bend to swift's way using the array-representation of a dict
b) Use String
or Int
as your key-type
c) Use a custom decoder
d) Use the RawRepresentable
-Protocol