Декодирование enum в Swift 5 - это НЕ МОЖЕТ быть таким сложным - PullRequest
0 голосов
/ 08 мая 2020

Последние 3-4 часа я пытался заставить эту глупую штуку правильно декодировать это перечисление, и теперь я невероятно разочарован этим! У меня есть строка json, возвращаемая из API, которая выглядит так:

[
  {
    "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)
        }
    }
}

Что, черт возьми, я делаю неправильно!? Любая помощь будет принята с благодарностью!

Ответы [ 2 ]

2 голосов
/ 08 мая 2020

Для синтаксического анализа 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:). Это будет обработано компилятором автоматически.

1 голос
/ 08 мая 2020

Здесь все, что вам нужно.

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