[英]Decoding array based JSON in Swift
I've got a WebSocket that uses an array format of [command, data] to exchange messages.我有一个 WebSocket,它使用 [command, data] 的数组格式来交换消息。 I'm struggling with the Swift Decoder to handle the mixed formats of the data portion.
我正在努力使用 Swift 解码器来处理数据部分的混合格式。 For instance Message #1:
例如消息 #1:
["CFG",{"dimmerDelay":5000,"keyboardShortcuts":true}]
Message #2:消息 #2:
["LFM",true]
I'm using this to decode Message #1我正在使用它来解码消息 #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
}
What I really want is to split this into a container more like this:我真正想要的是把它拆分成一个更像这样的容器:
struct Message: Decodable {
let command: String
let data: String
}
Then if the message is of type "CFG" I would pass the data to a decoder that would create the Config object.然后,如果消息是“CFG”类型,我会将数据传递给解码器,该解码器将创建配置 object。 If the message is of type "LFM" I would check to ensure the result is true and if the message is of another type, I'd pass that data to another decoder that would create the relevant decoded objects.
如果消息是“LFM”类型,我会检查以确保结果为真,如果消息是另一种类型,我会将该数据传递给另一个解码器,该解码器将创建相关的解码对象。
There are several approaches, but assuming you know all the "command" strings and what they map to, you can take an enum approach:有几种方法,但假设您知道所有“命令”字符串以及它们 map 的用途,您可以采用枚举方法:
enum Message {
case config(Config)
case lfm(Bool)
}
To make this Decodable, you just need a switch statement:要使这个可解码,你只需要一个 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)"))
}
}
}
After decoding, you'll use a switch statement to determine what you have:解码后,您将使用 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.