Swift enum Codable со связанными типами

У меня есть структура с двумя типами, оба 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)
    }
}

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

Dávid Pásztor 21.01.2019 16:40

@DávidPásztor, потребуется пользовательское руководство init(from:) для UDPCommandData, поскольку автоматическое создание кода для enum with associated value не реализовано.

user28434'mstep 21.01.2019 17:17
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
2
296
0

Другие вопросы по теме