У меня есть структура с двумя типами, оба enum, один из них с разными связанными значениями в каждом случае enum (см. Код). Есть ли обходной путь, чтобы избежать включения UDPCommand? Каждый добавленный случай делает переключение более длинным и повторяющимся кодом. И нужно сделать на энкодере снова. Я пытаюсь сделать это с помощью дженериков, но не могу заставить это работать. Спасибо
struct UDPMessage {
let command: UDPCommand
var data: UDPCommandData
func jsonString() -> String {
let encoder = JSONEncoder()
guard let data = try? encoder.encode(self) else { return "" }
guard let string = String(data: data, encoding: .utf8) else { return "" }
return string
}
}
enum UDPCommand: String, Codable {
case DISCOVER
case FILTER
case TOGGLE
case SWIPE_CHAT
case FORWARD
}
enum UDPCommandData {
case discover(Discover)
case filter(Filter)
case toggle(Toggle)
case swipe(SwipeChat)
case forwardedMessage(ForwardedMessage)
case unkkown
}
extension UDPMessage: Codable {
private enum CodingKeys: String, CodingKey {
case command, data
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let command = try container.decode(UDPCommand.self, forKey: .command)
switch command {
case .DISCOVER:
let data = try container.decode(Discover.self, forKey: .data)
self.init(command: command, data: UDPCommandData.discover(data))
case .FILTER:
let data = try container.decode(Filter.self, forKey: .data)
self.init(command: command, data: UDPCommandData.filter(data))
case .TOGGLE:
let data = try container.decode(Toggle.self, forKey: .data)
self.init(command: command, data: UDPCommandData.toggle(data))
case .SWIPE_CHAT:
let data = try container.decode(SwipeChat.self, forKey: .data)
self.init(command: command, data: UDPCommandData.swipe(data))
default:
self.init(command: command, data: UDPCommandData.unkkown)
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.command, forKey: .command)
try self.data.encode(to: encoder)
}
}
@DávidPásztor, потребуется пользовательское руководство init(from:) для UDPCommandData, поскольку автоматическое создание кода для enum with associated value не реализовано.





Зачем вообще нужен пользовательский метод
init(from:)? Компилятор должен быть в состоянии автоматически синтезировать это для вас. Кстати, случаиUDPCommandдолжны соответствовать соглашению об именах Swift и быть в нижнем регистре CamelCase. Вы можете просто присвоитьStringrawValue как версию в верхнем регистре, если это то, что приходит из JSON. Какenum UDPCommand: String, Codable { case discover = "DISCOVER"...