在Swift中动态解码任意json字段
发布时间:2020-12-14 04:43:25 所属栏目:百科 来源:网络整理
导读:TL; DR 有没有办法可以使用JSONDecoder并编写一个函数,它只是从给定的json读出指定的可解码类型的字段值? 成像我有以下json: { "product":{ "name":"PR1","price":20 },"employee":{ "lastName":"Smith","department":"IT","manager":"Anderson" }} 我有2
TL; DR
有没有办法可以使用JSONDecoder并编写一个函数,它只是从给定的json读出指定的可解码类型的字段值? 成像我有以下json: { "product":{ "name":"PR1","price":20 },"employee":{ "lastName":"Smith","department":"IT","manager":"Anderson" } } 我有2个可解码结构: struct Product: Decodable { var name: String var price: Int } struct Employee: Decodable { var lastName: String var department: String var manager: String } 我想写一个函数 func getValue<T:Decodable>(from json: Data,field: String) -> T { ... } 所以我可以这样称呼它: let product: Product = getValue(from: myJson,field: "product") let employee: Employee = getValue(from: myJson,field: "employee") 这是可能的JSONDecoder或我应该搞乱JSONSerialization,首先读出给定的json的“子树”,然后将其传递给解码器?在swift中似乎不允许在泛型函数中定义结构. 解决方法
可解码假定您在设计时知道所需的一切以启用静态类型.你想要的动态越多,你就越有创意.在这种情况下,定义通用编码键结构非常方便:
/// A structure that holds no fixed key but can generate dynamic keys at run time struct GenericCodingKeys: CodingKey { var stringValue: String var intValue: Int? init?(stringValue: String) { self.stringValue = stringValue } init?(intValue: Int) { self.intValue = intValue; self.stringValue = "(intValue)" } static func makeKey(_ stringValue: String) -> GenericCodingKeys { return self.init(stringValue: stringValue)! } static func makeKey(_ intValue: Int) -> GenericCodingKeys { return self.init(intValue: intValue)! } } /// A structure that retains just the decoder object so we can decode dynamically later fileprivate struct JSONHelper: Decodable { let decoder: Decoder init(from decoder: Decoder) throws { self.decoder = decoder } } func getValue<T: Decodable>(from json: Data,field: String) throws -> T { let helper = try JSONDecoder().decode(JSONHelper.self,from: json) let container = try helper.decoder.container(keyedBy: GenericCodingKeys.self) return try container.decode(T.self,forKey: .makeKey(field)) } let product: Product = try getValue(from: json,field: "product") let employee: Employee = try getValue(from: json,field: "employee") (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |