4

Suppose I have a struct like this:

struct Result: Decodable {
   let animal: Animal?
}

And an enum like this:

enum Animal: String, Decodable {
   case cat = "cat"
   case dog = "dog"
}

but the JSON returned is like this:

{
  "animal": ""
}

If I try to use a JSONDecoder to decode this into a Result struct, I get Cannot initialize Animal from invalid String value as an error message. How can I properly decode this JSON result into a Result where the animal property is nil?

ruhm
  • 1,357
  • 2
  • 9
  • 10

1 Answers1

4

If you want to treat an empty string as nil, you need to implement your own decoding logic. For example:

struct Result: Decodable {
    let animal: Animal?

    enum CodingKeys : CodingKey {
        case animal
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let string = try container.decode(String.self, forKey: .animal)

        // here I made use of the fact that an invalid raw value will cause the init to return nil
        animal = Animal.init(rawValue: string)
    }
}
Sweeper
  • 213,210
  • 22
  • 193
  • 313