jsonswiftdecoderjsondecoder

Make Swift JSONDecoder not fail when type on key not match


I have one simple struct like that:

struct Object: Codable {
    let year: Int?
    …
}

It's fine when decode JSON like { "year": 10, … } or no year in JSON.
But will fail decode when JSON has different type on key: { "year": "maybe string value" }

How could I not fail decode process when type not match on the Optional property?

Thanks.


Solution

  • Implement init(from:) in struct Object. Create enum CodingKeys and add the cases for all the properties you want to parse.

    In init(from:) parse the keys manually and check if year from JSON can be decoded as an Int. If yes, assign it to the Object's year property otherwise don't.

    struct Object: Codable {
        var year: Int?
    
        enum CodingKeys: String,CodingKey {
            case year
        }
    
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            if let yr = try? values.decodeIfPresent(Int.self, forKey: .year) {
                year = yr
            }
        }
    }
    

    Parse the JSON response like,

    do {
        let object = try JSONDecoder().decode(Object.self, from: data)
        print(object)
    } catch {
        print(error)
    }
    

    Example:

    1. If JSON is { "year": "10"}, object is: Object(year: nil)
    2. If JSON is { "year": 10}, object is: Object(year: Optional(10))