带有关联类型的Swift枚举Codable

时间:2019-01-21 15:30:31

标签: swift generics codable

我有一个具有两种类型的结构,都为枚举,在每种枚举情况下,其中一种具有不同的关联值(请参见代码)。有什么解决方法可以避免在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)
    }
}

0 个答案:

没有答案