快速工厂将可解码类型转换为可能的结果之一

问题描述 投票:0回答:1

注意:看到了这个问题,但似乎没有解决问题: 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
swift codable
1个回答
0
投票

使用 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)
© www.soinside.com 2019 - 2024. All rights reserved.