在动态类型/对象上使用Codable

问题描述:

您好我有以下结构嵌套在一个更大的结构中,从api调用返回,但我无法设法编码/解码此部分。我遇到的问题是customKey和customValue都是动态的。在动态类型/对象上使用Codable

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

我想是这样var values: [String:String]但是,这显然是不工作,因为它不是真正的[String:String]阵列。

+0

@vadian我不明白这是怎么复制的任何这些的问题。我现在把这个问题修改得更清楚了。 – Reshad

+0

我明白并重新提出了这个问题:简短的回答:你不能在动态密钥中使用'Codable'。 – vadian

+0

你能推荐另一种方法来做到这一点? – Reshad

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

事实是,所有的按键都在运行时知道,如果你知道去哪里找:

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) 
+0

非常感谢您的快速响应。如果我在JSON中有其他键可以正常解码的值旁边,这将如何应用,我是否添加了一个正常的枚举容器? – Reshad

+0

我对你的新要求感到困惑。你能编辑JSON来展示它的一个例子吗? –

+0

我编辑了JSON。我的意思是,我编码和解码的实际对象不仅仅是值 - 键 - >对象。 :) – Reshad