I just tried this:
let test = "{ \"de\": \"Bisasam\", \"en\": \"Bulbasaur\" }"
let data = test.data(using: .utf8)!
do {
let result = try JSONDecoder().decode([String: String].self, from: data)
print("") // breakpoint here works
} catch {
print("")
}
This works fine, however when I try to do this instead:
enum Lg: String, CaseIterable, Decodable {
case deutsch = "de"
case english = "en"
}
let test = "{ \"de\": \"Bisasam\", \"en\": \"Bulbasaur\" }"
let data = test.data(using: .utf8)!
do {
let result = try JSONDecoder().decode([Lg: String].self, from: data)
print("")
} catch {
print("") // breakpoint here
}
With this error:
▿ DecodingError ▿ typeMismatch : 2 elements
- .0 : Swift.Array ▿ .1 : Context
- codingPath : 0 elements
- debugDescription : "Expected to decode Array but found a dictionary instead."
- underlyingError : nil
What am I doing wrong?
Thanks for your help
When you use a non-
Stringnon-Inttype as the dictionary key,Dictionary'sDecodableimplementation expects an array of key value pairs, i.e.:This decodes to
[.deutsch: "foo", .english: "bar"].JSON keys can only be strings after all, and the
Decodableimplementation doesn't know how to convert a randomDecodablevalue into a string. It could have been made to check forRawRepresentablewithRawValue == String, but it wasn't.One thing that it does check for though, is
CodingKeyRepresentable, if you just conformLgto that, then you can decode a JSON dictionary correctly.Note that I also conformed it to
CodingKeyto make it easier to write thecodingKeyproperty required byCodingKeyRepresentable.