0

I am trying to decode the response I am receiving from API, the response can be 0/1/"skip" so it can be Int or String. How do I define this variable? I have tried to define as: String / String? / Int / Int? , but none of these worked, all throwing an error.

Code:

struct DatesData: Decodable {
   let state: String?
   let date: String?   <-- getting the error here

   enum CodingKeys: String, CodingKey {
     case state
     case date = "dates"
   }
}

Response is coming in like this:

    {
        dates = "2021-03-26";
        state = 0;
    },
    {
        dates = "2021-03-27";
        state = 1;
    },
    {
        dates = "2021-03-28";
        state = skip;
    }

Thanks in advance

Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
testkn
  • 1
  • There's already an answer for this question: https://stackoverflow.com/questions/48297263/how-to-use-any-in-codable-type – Rob Jan 03 '21 at 13:10
  • @AlBlue I don't see how I can use that answer to solve my issue – testkn Jan 03 '21 at 15:22

1 Answers1

0

In this particular case I'd recommend to create an enum for the 3 states and decode the JSON manually

enum State { case on, off, skip }

struct DatesData: Decodable {
    let state: State
    let date: String
    
    enum CodingKeys: String, CodingKey {
        case state
        case date = "dates"
    }
    
    init(from decoder : Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        do {
            let intState = try container.decode(Int.self, forKey: .state)
            self.state = intState == 1 ? .on : .off
        } catch DecodingError.typeMismatch {
            let stringState = try container.decode(String.self, forKey: .state)
            if stringState == "skip" {
                state = .skip
            } else {
                throw DecodingError.dataCorruptedError(forKey: .state, in: container, debugDescription: "String must be 'skip'")
            }
        }
        date = try container.decode(String.self, forKey: .date)
    }
}

You could also throw an error if the integer is neither 0 nor 1.

vadian
  • 274,689
  • 30
  • 353
  • 361
  • Thanks, how can I access the param? If I try if (arr.state == State.on) it throws error – testkn Jan 03 '21 at 15:20
  • The decoded object is obviously an array, so you have to select one item e.g. `if arr[0].state == .on` – vadian Jan 03 '21 at 15:39