Ad

Error Decoding Data With Codable Even Though Parameters Are Optional

- 1 answer

I have the following struct:

struct Recipe: Codable {
    @DocumentID var id: String?
    var minutes: Int?
    
    init(id: String, minutes: Int) {
        
        self.id = id
        self.minutes = minutes
    }
    
    init(from decoder: Decoder) throws {
        
        enum DecodingKeys: CodingKey {
            case minutes
          }
        
        let container = try decoder.container(keyedBy: DecodingKeys.self)
        minutes = try container.decode(Int.self, forKey: .minutes)
    }
}

I'm decoding from a source where minutes is null, so I get the following error message:

Error parsing response data: keyNotFound(DecodingKeys(stringValue: "minutes", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key DecodingKeys(stringValue: \"minutes\", intValue: nil) (\"minutes\").", underlyingError: nil))

However, I thought marking minutes as optional in struct Recipe was sufficient to handle this case? Is there something else I need to implement?

Ad

Answer

When you implement init(from:) manually you need to use the decodeIfPresent(_:forKey:) variant for optional properties. The decode(_:forKey:) method throws an error if a nullable field in the JSON data is absent whereas the decodeIfPresent(_:forKey:) method just returns nil.

Try this:

init(from decoder: Decoder) throws {

    enum DecodingKeys: CodingKey {
        case minutes
      }

    let container = try decoder.container(keyedBy: DecodingKeys.self)
    minutes = try container.decodeIfPresent(Int.self, forKey: .minutes)
}
Ad
source: stackoverflow.com
Ad