繁体   English   中英

Swift 中的基于解码阵列的 JSON

[英]Decoding array based JSON in Swift

我有一个 WebSocket,它使用 [command, data] 的数组格式来交换消息。 我正在努力使用 Swift 解码器来处理数据部分的混合格式。 例如消息 #1:

["CFG",{"dimmerDelay":5000,"keyboardShortcuts":true}]

消息 #2:

["LFM",true]

我正在使用它来解码消息 #1

struct Message: Decodable {
    let command: String
    let config: Config
    
    init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        command = try container.decode(String.self)
        config = try container.decode(Config.self)
        }
    }

struct Config: Decodable {
    let dimmerDelay: Int
    let keyboardShortcuts: Bool
    }

我真正想要的是把它拆分成一个更像这样的容器:

struct Message: Decodable {
    let command: String
    let data: String
    }

然后,如果消息是“CFG”类型,我会将数据传递给解码器,该解码器将创建配置 object。 如果消息是“LFM”类型,我会检查以确保结果为真,如果消息是另一种类型,我会将该数据传递给另一个解码器,该解码器将创建相关的解码对象。

有几种方法,但假设您知道所有“命令”字符串以及它们 map 的用途,您可以采用枚举方法:

enum Message {
    case config(Config)
    case lfm(Bool)
}

要使这个可解码,你只需要一个 switch 语句:

extension Message: Decodable {
    init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        let command = try container.decode(String.self)

        switch command {
        case "CFG":
            self = .config(try container.decode(Config.self))

        case "LFM":
            self = .lfm(try container.decode(Bool.self))

        default:
            throw DecodingError.typeMismatch(Message.self,
                                             .init(codingPath: [],
                                                   debugDescription: "Unknown command: \(command)"))
        }
    }
}

解码后,您将使用 switch 语句来确定您拥有什么:

let message = try JSONDecoder().decode(Message.self, from: json)

switch message {
case .config(let config): handleConfig(config)
case .lfm(let bool): handleLFM(bool)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM