如何解决在 Swift 中解码基于数组的 JSON
我有一个 WebSocket,它使用 [command,data] 的数组格式来交换消息。我正在努力使用 Swift Decoder 来处理数据部分的混合格式。例如消息 #1:
@Composable
fun ListItem() {
Surface(
modifier = Modifier.fillMaxWidth(),shape = RoundedCornerShape(8.dp),elevation = 2.dp
) {
Row(
modifier = Modifier.fillMaxWidth().preferredHeight(IntrinsicSize.Max),verticalAlignment = Alignment.CenterVertically
) {
Column(
modifier = Modifier
.padding(8.dp),horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Code")
Text(text = "2456")
}
Spacer(
modifier = Modifier
.preferredWidth(1.dp)
.fillMaxHeight()
.background(color = Color.Black.copy(0.12f))
)
Spacer(modifier = Modifier.weight(1f))
Text(
modifier = Modifier
.padding(horizontal = 8.dp,vertical = 34.dp),text = "Some name"
)
Spacer(modifier = Modifier.weight(1f))
}
}
}
消息 #2:
["CFG",{"dimmerDelay":5000,"keyboardShortcuts":true}]
我用它来解码消息 #1
["LFM",true]
我真正想要的是将其拆分成一个更像这样的容器:
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
}
然后,如果消息是“CFG”类型,我会将数据传递给一个解码器,该解码器将创建 Config 对象。如果消息是“LFM”类型,我会检查以确保结果为真,如果消息是另一种类型,我会将该数据传递给另一个解码器,该解码器将创建相关的解码对象。
解决方法
有几种方法,但假设您知道所有“命令”字符串及其映射的内容,您可以采用枚举方法:
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)
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。