-1

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.

user25917
  • 797
  • 7
  • 18

1 Answers1

1

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))
PGDev
  • 23,751
  • 6
  • 34
  • 88
  • Could I custom the JSONDecoder to make that happen but not custom the Codable struct? That's pain to implement all things like that. – user25917 Jun 28 '19 at 18:30
  • Yes it it. Its better you prefer changing the API response to return consistent types for the keys. – PGDev Jun 28 '19 at 18:31
  • There is no other way to handle that. You cannot customize the JSONDecoder for this kind of implementation. – PGDev Jun 28 '19 at 18:33
  • I use Scripting Bridge to communicate with other Mac app via Apple Event. So I can not change the response. In face I should assert all the response from other side will change in some times. But little change should be OK. That's is user expect. – user25917 Jun 28 '19 at 18:35
  • Thank your reply. I hope Apple will improve the decoder to make more custom options for us. – user25917 Jun 28 '19 at 18:36