在动态类型/对象上使用Codable [英] Using Codable on a dynamic type/object

查看:53
本文介绍了在动态类型/对象上使用Codable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将以下结构嵌套在一个更大的结构中,该结构是通过api调用返回的,但是我无法对这部分进行编码/解码。我遇到的问题是customKey和customValue都是动态的。

Hi I have the following structure nested in a bigger structure that is returned from an api call but I can't manage to encode/decode this part. The problem I am having is that the customKey and customValue are both dynamic.

{
    "current" : "a value"
    "hash" : "some value"
    "values": {
        "customkey": "customValue",
        "customKey": "customValue"
    }
}

我尝试了类似 var值的方法:[String:String] 但这显然不是之所以起作用,是因为它实际上不是 [String:String] 的数组。

I tried something like var values: [String:String] But that is obviously not working because its not actually an array of [String:String].

推荐答案

由于您已链接到我对另一个问题的答案,因此我将扩展该问题以回答您的问题。

Since you linked to my answer to another question, I will expand that one to answer yours.

真相是,如果您知道在哪里运行,则所有键在运行时都是已知的看起来:

Truth is, all keys are known at runtime if you know where to look:

struct GenericCodingKeys: CodingKey {
    var intValue: Int?
    var stringValue: String

    init?(intValue: Int) { self.intValue = intValue; self.stringValue = "\(intValue)" }
    init?(stringValue: String) { self.stringValue = stringValue }

    static func makeKey(name: String) -> GenericCodingKeys {
        return GenericCodingKeys(stringValue: name)!
    }
}


struct MyModel: Decodable {
    var current: String
    var hash: String
    var values: [String: String]

    private enum CodingKeys: String, CodingKey {
        case current
        case hash
        case values
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        current = try container.decode(String.self, forKey: .current)
        hash = try container.decode(String.self, forKey: .hash)

        values = [String: String]()
        let subContainer = try container.nestedContainer(keyedBy: GenericCodingKeys.self, forKey: .values)
        for key in subContainer.allKeys {
            values[key.stringValue] = try subContainer.decode(String.self, forKey: key)
        }
    }
}

用法:

let jsonData = """
{
    "current": "a value",
    "hash": "a value",
    "values": {
        "key1": "customValue",
        "key2": "customValue"
    }
}
""".data(using: .utf8)!

let model = try JSONDecoder().decode(MyModel.self, from: jsonData)

这篇关于在动态类型/对象上使用Codable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆