[英]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.