【发布时间】:2019-02-14 22:59:06
【问题描述】:
问题基本上归结于此。我的应用正在接收这种 JSON 格式的消息:
{
"action": "ready",
"data": null
}
或
{
"action": "error",
"data": {
"code": String,
"exception": String,
"status": Int
}
}
或
{
"action": "messageRequest",
"data": {
"recipientUserId": String,
"platform": String,
"content": String
}
}
或
{
"action": "tabsChange",
"data": {
"roomsTabs": [{
"configuration": {
"accessToken": STRING,
"url": STRING,
"userId": STRING
},
"id": STRING,
"isOnline": BOOLEAN,
"isUnread": BOOLEAN,
"lastActive": NUMBER,
"name": STRING,
"participantBanned": BOOLEAN,
"platform": STRING,
"secondParticipant": {
"id": STRING,
"platform": STRING,
"userId": STRING
},
"secondParticipantId": STRING,
"state": STRING,
"unreadMessages": NUMBER
]}
}
}
如您所见,数据对象具有不同的结构,具体取决于消息,并且可能会变大(其中有 10 多个)。 我不想逐个字段地手动解析所有内容,理想的解决方案当然是:
struct ChatJsCommand: Codable {
let action: String
let data: Any?
}
self.jsonDecoder.decode(ChatJsCommand.self, from: jsonData))
当然因为 Any 这不能符合 Codable。我当然可以只手动提取动作字段,创建动作映射(枚举)到结构类型,然后执行JSONDecoder().decode(self.commandMap[ActionKey], data: jsonData)。此解决方案可能还需要对适当的结构类型进行一些转换,以便在解析后使用对象。
但也许有人有更好的方法?所以这个类不是300行吗?任何想法都非常感谢。
【问题讨论】:
-
不,只有 10 条消息,但希望避免使用 blob 结构进行解析,不过感谢您的建议。
-
基本上,您只需使用自定义初始化,以便您可以解码
action并使用它的值告诉您使用什么结构来解码data。查看链接的问题和答案。 -
@matt 我不确定它是否完全重复。这与未知键无关,因此您不需要在此处自定义
CodingKeys。 -
@Sulthan 如果你愿意,你可以取消重复,那是你的特权;我不会生气的。但在我看来,“我如何根据第一个键的值对第二个键进行不同的处理”这个问题已经在 SO 上得到了完全的回答。