1

I've been trying for the past 3-4 hours to get this stupid thing to decode this enum correctly and now am incredibly frustrated with this! I have a json string returning from an API that looks like this:

[
  {
    "contractType": 0
  }
]

I am trying to map THAT to an enum called ContractType. This is my whole ContractType enum

enum ContractType: Int {
    case scavenger = 0
}

and this is my extension I tried to make it conform to the Codable protocol.

extension ContractType: Codable {
    enum Key: Int, CodingKey {
        case rawValue
    }

    enum CodingError: Error {
        case unknownValue
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: Key.self)
        let rawValue = try? container.decode(Int.self, forKey: .rawValue)

        switch rawValue {
        case 0:
            self = .scavenger
        default:
            throw CodingError.unknownValue
        }
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: Key.self)
        switch self {
        case .scavenger:
            try container.encode(0, forKey: .rawValue)
        }
    }
}

What the heck am I doing wrong!? Any help would be greatly appreciated!

Cory
  • 658
  • 3
  • 7
  • 19

2 Answers2

3

To parse the above JSON response, Codable models should be,

struct Response: Codable {
    let contractType: ContractType
}

enum ContractType: Int, Codable {
    case scavenger = 0
}

Now, parse the JSON data like so,

do {
    let response = try JSONDecoder().decode([Response].self, from: data)
    print(response)
} catch {
    print(error)
}

There is no need to explicitly implement init(from:) and encode(to:). It will be handled by the compiler automatically.

PGDev
  • 23,751
  • 6
  • 34
  • 88
  • 1
    I appreciate the quick response, your answer and Frankenstein's answer (below) are BOTH the correct answers! Thanks again! I was able to get this to work and it turns out it really ISN'T as hard as I was trying to make it! lol – Cory May 10 '20 at 22:52
3

This all you need here.

struct Contract: Codable {
    var contractType: ContractType

    enum ContractType: Int, Codable {
        case scavenger
    }
}

do {
    let contract = try JSONDecoder().decode([Contract].self, from: json)
    print(contract.contractType)
} catch {
    print(error)
}
Frankenstein
  • 15,732
  • 4
  • 22
  • 47