Я получаю доступ к API общественного транспорта и сопоставляю ответ с моделью, используя Codable и Alamofire 5.
В основном это работает, но API не нормализован правильно, то есть я получаю разные типы данных для одних и тех же свойств (линии шины могут быть либо Int, либо String и т. Д.)
Я пытаюсь отобразить свойство типа транспортных средств в перечисление, которое выглядит следующим образом:
enum VehiculeType {
case bus
case trolleybus
case tram
init?(rawValue: String) {
switch rawValue {
case "AB", "ABA", "ABAA":
self = .bus
break
case "TBA", "TBAA":
self = .trolleybus
case "TW6", "TW7", "TW2":
self = .tram
default: return nil
}
}
}
А вот моя модель, которая до сих пор правильно декодирует.
struct Departure: Codable {
// let lineCode: String
let destination: String
let waitingTime: Int
let waitingMilliseconds: Int
let reroute: String
// let vehiculeType: VehiculeType?
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
destination = try container.decode(String.self, forKey: .destination)
waitingTime = try container.decode(Int.self, forKey: .waitingTime, transformFrom: String.self) ?? 0
waitingMilliseconds = try container.decode(Int.self, forKey: .waitingMilliseconds)
reroute = try container.decode(String.self, forKey: .reroute)
// vehiculeType = try container.decodeIfPresent(String.self, forKey: .vehiculeType, transformFrom: String.self) // This does not work. Correct implementation needed here
}
}
extension Departure {
enum CodingKeys: String, CodingKey {
case destination = "destination"
case waitingTime = "attente"
case waitingMilliseconds = "attenteMilli"
case reroute = "deviation"
// case vehiculeType
}
}
Также у меня есть KeyedDecodingContainer
расширение, реализованное для преобразования некоторых типов в другие. Поплавок например ..
Как я могу автоматически сопоставить enum с моей моделью, когда она декодируется, чтобы я прикреплял к ней значения enum (см. Enum) вместо Strings? Могу ли я подчинить enum непосредственно Codable?