I am having issues with decoding JSON, where some of the fields returned from the server as not available on the client. Take a look at the following code. The JSON consists of three roles but the Role enum only consists of student and staff. How can I successfully decode JSON ignoring the missing faculty role.
let json = """
[
{
"role": "student"
},
{
"role": "staff"
},
{
"role": "faculty"
},
]
"""
struct User: Decodable {
let role: Role
}
enum Role: String, Decodable {
case student
case staff
private enum CodingKeys: String, CodingKey {
case student = "student"
case staff = "staff"
}
}
let decoded = try! JSONDecoder().decode([User].self, from: json.data(using: .utf8)!)
print(decoded)
Currently, I get the following error:
error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 2", intValue: 2), CodingKeys(stringValue: "role", intValue: nil)], debugDescription: "Cannot initialize Role from invalid String value faculty", underlyingError: nil))
2
Answers
It will always throw that error because the decoder will be presented with "role": "faculty" which it won’t recognize. Thus if you really really want to ignore it you can ditch the decoder and do something like this:
Or you can add the missing case and filter the array:
You’ll need to create a top-level object to hold the
[User]
:Then, give it a custom decoder that will check for malformed
role
keys and ignore those Users, but won’t ignore other errors:If you define
User.CodingKeys
, then you can skip the Ignore struct:With that, you can get rid of the Ignore struct and replace this line:
with: