Swift Decodable Optional Key Swift Decodable Optional Key json json

Swift Decodable Optional Key


You can use the following KeyedDecodingContainer function:

func contains(_ key: KeyedDecodingContainer.Key) -> Bool

Returns a Bool value indicating whether the decoder contains a value associated with the given key. The value associated with the given key may be a null value as appropriate for the data format.

For instance, to check if the "age" key exists before requesting the corresponding nested container:

struct Person: Decodable {    let firstName, lastName: String    let age: Int?    enum CodingKeys: String, CodingKey {        case firstName = "firstname"        case lastName = "lastname"        case age    }    enum AgeKeys: String, CodingKey {        case realAge = "realage"        case fakeAge = "fakeage"    }    init(from decoder: Decoder) throws {        let values = try decoder.container(keyedBy: CodingKeys.self)        self.firstName = try values.decode(String.self, forKey: .firstName)        self.lastName = try values.decode(String.self, forKey: .lastName)        if values.contains(.age) {            let age = try values.nestedContainer(keyedBy: AgeKeys.self, forKey: .age)            self.age = try age.decodeIfPresent(Int.self, forKey: .realAge)        } else {            self.age = nil        }    }}


I had this issue and I found this solution, just in case is helpful to somebody else:

let ageContainer = try? values.nestedContainer(keyedBy: AgeKeys.self, forKey: .age)self.age = try ageContainer?.decodeIfPresent(Int.self, forKey: .realAge)

If you have an optional container, using try? values.nestedContainer(keyedBy:forKey) you don't need to check if the container exist using contains(.


Can you try pasting your sample JSON into quicktype to see what types it infers? Based on your question, I pasted your samples and got:

struct UserInfo: Codable {    let firstname: String    let age: Age?    let lastname: String}struct Age: Codable {    let realage: Int?}

Making UserInfo.age and Age.realage optionals works, if that's what you're trying to accomplish.