微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Swift中动态解码任意json字段

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")

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐