解码 Swift 中的枚举 5 - 这不可能这么难

Decoding enum in Swift 5 - This CANNOT be this hard

在过去的 3-4 个小时里,我一直在尝试让这个愚蠢的东西正确解码这个枚举,现在我对此感到非常沮丧!我有一个从 API 返回的 json 字符串,如下所示:

[
  {
    "contractType": 0
  }
]

我正在尝试将其映射到名为 ContractType 的枚举。这是我的全部 ContractType 枚举

enum ContractType: Int {
    case scavenger = 0
}

这是我的扩展,我试图让它符合 Codable 协议。

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)
        }
    }
}

我到底做错了什么!?任何帮助将不胜感激!

解析上面的JSON响应Codable模型应该是,

struct Response: Codable {
    let contractType: ContractType
}

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

现在,像这样解析 JSON data

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

无需显式实现 init(from:)encode(to:)。它将由编译器自动处理。

这就是你所需要的。

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)
}