我有一个生成不同 json 对象的 websocket。对象不能包含任何公共字段
{
"type": "apple",
"kind": "fruit",
"eatable": true
}
{
"item": "key",
"active": true
}
{
"tool": "screwdriver",
"original": "toolBox",
"cross-head": true
}
Run Code Online (Sandbox Code Playgroud)
我有一个它们的类列表(它们可能包含一些逻辑),所以我需要解析它以映射一些具有某种层次结构的模型,例如尝试解析水果如果它们失败尝试解析键如果它们尝试解析工具箱失败。有时我需要添加一些新类来解析一些对象和一些新字段到现有类。
如何组织采摘类进行解析?
更新
你可以这样做:
首先你声明你的类型符合Decodable
协议:
struct Fruit : Decodable {
let type : String
let kind : String
let eatable : Bool
}
struct Tool : Decodable {
let tool : String
let original : String
let crossHead : Bool
enum CodingKeys: String, CodingKey {
case tool = "tool"
case original = "original"
case crossHead = "cross-head"
}
}
Run Code Online (Sandbox Code Playgroud)
然后你扩展Decodable
到“反向”通用性的使用:
extension Decodable {
static func decode(data : Data, decoder : JSONDecoder = JSONDecoder()) -> Self? {
return try? decoder.decode(Self.self, from: data)
}
}
Run Code Online (Sandbox Code Playgroud)
然后JSONDecoder
,您可以扩展以在要测试的类型中尝试可解码类型:
extension JSONDecoder {
func decode(possibleTypes : [Decodable.Type], from data: Data) -> Any? {
for type in possibleTypes {
if let value = type.decode(data: data, decoder: self) {
return value
}
}
return nil
}
}
Run Code Online (Sandbox Code Playgroud)
最终您指定要尝试解码的类型:
let decodableTypes : [Decodable.Type] = [Fruit.self, Tool.self]
Run Code Online (Sandbox Code Playgroud)
然后您可以使用它来解码您的 JSON:
let jsonString = """
{
"tool": "screwdriver",
"original": "toolBox",
"cross-head": true
}
"""
let jsonData = jsonString.data(using: .utf8)!
let myUnknownObject = JSONDecoder().decode(possibleTypes: decodableTypes, from: jsonData)
Run Code Online (Sandbox Code Playgroud)
瞧!!!
现在decodableTypes
,只要符合Decodable
协议,您就可以根据需要添加任意数量的类型。
这不是最好的方法,因为如果您有很多类型,它就不是最佳方法,但是这样您就不需要在数据中添加区分字段。
归档时间: |
|
查看次数: |
783 次 |
最近记录: |