注意:看到了这个问题,但似乎没有解决问题: Swift 根据响应类型动态选择 JSON 字段值的 Codable 结构
自从从网络调用响应解码以来,我事先不知道运行时类型。因此,目前我正在尝试在 try/catch 中一个接一个地进行解码,但我正在寻找一种基于通用属性的更简洁的方法,该属性可用于理论上的“开关”来定义运行时类型。
我知道他们总是有一个带有键的字段可以映射到最终类型,所以这里有什么技巧可以使用吗?我正在考虑一些类似于联合类型的事情,其中包含可能的结果之一。这是我的示例代码:
struct Result1: Codable {
let resultType: String = "result1" // this is always the case in the JSON for this particular type of result
...
let other fields which are unique to this type of result
}
struct Result2: Codable {
let resultType: String = "result2" // always this field in the json for this result type
...
let other fields which are unique to this type of result ...
}
... Lot's of other types ...
struct ResultN: Codable {
let resultType: String = "resultN"
....
}
// Now how to decode the "either Result1 or Result2 or .... ResultN
let value = try JSONDecoder().decode(????.self, from: data) // don't know what type it will be yet
if value is Result1 { ... handle this case ... }
if value is Result2 { ... handle this case ... }
....
if value is ResultN { ..... }
也许解码为通用 Json 字典,然后从那里映射到正确的类型?
注:
考虑这种机制(但有很多样板):
let dict = try JSONSerialization.jsonObject(with: data) as? [String: Any]
switch dict["resultType"] {
case "result1" : ... decode to res1
...
case "resultN" : .... decode to resN
使用 resultType 到 Codable 的字典也许就足够了 🤔 (JSON 解码运行两次以获得
dict
和 value
)
let map: Dictionary<String, Codable.Type> = [
"result1": Result1.self,
"result2": Result2.self,
// ...
"resultN": ResultN.self
]
let codable = map[dict["resultType"]]
let value = try! JSONDecoder().decode(codable!, from: data)