在动态 type/object 上使用 Codable
Using Codable on a dynamic type/object
您好,我将以下结构嵌套在从 api 调用返回的更大结构中,但我无法 encode/decode 这部分。我遇到的问题是 customKey 和 customValue 都是动态的。
{
"current" : "a value"
"hash" : "some value"
"values": {
"customkey": "customValue",
"customKey": "customValue"
}
}
我尝试了 var values: [String:String]
之类的方法,但这显然不起作用,因为它实际上不是 [String:String]
.
的数组
由于您链接到我对另一个问题的回答,我将扩展那个问题来回答您的问题。
事实是,如果您知道在何处查找,则所有密钥在运行时都是已知的:
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)
简化的答案,它正在使用字典 [String: String](instatead of String 你可以使用其他结构):
let jsonData = """
{
"current": "a value",
"hash": "a value",
"values": {
"key1": "customValue",
"key2": "customValue"
}
}
""".data(using: .utf8)!
struct MyModel: Decodable {
var current: String
var hash: String
var values: [String: String]
}
let model = try JSONDecoder().decode(MyModel.self, from: jsonData)
for (key,value) in model.values {
print("key: \(key) value: \(value)")
}
您好,我将以下结构嵌套在从 api 调用返回的更大结构中,但我无法 encode/decode 这部分。我遇到的问题是 customKey 和 customValue 都是动态的。
{
"current" : "a value"
"hash" : "some value"
"values": {
"customkey": "customValue",
"customKey": "customValue"
}
}
我尝试了 var values: [String:String]
之类的方法,但这显然不起作用,因为它实际上不是 [String:String]
.
由于您链接到我对另一个问题的回答,我将扩展那个问题来回答您的问题。
事实是,如果您知道在何处查找,则所有密钥在运行时都是已知的:
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)
简化的答案,它正在使用字典 [String: String](instatead of String 你可以使用其他结构):
let jsonData = """
{
"current": "a value",
"hash": "a value",
"values": {
"key1": "customValue",
"key2": "customValue"
}
}
""".data(using: .utf8)!
struct MyModel: Decodable {
var current: String
var hash: String
var values: [String: String]
}
let model = try JSONDecoder().decode(MyModel.self, from: jsonData)
for (key,value) in model.values {
print("key: \(key) value: \(value)")
}