下面是我的JSON,无法解码(使用CodingKeys) region 键中的数据是一个词典(“ IN-WB”,“ IN-DL”等。。。),因为这些键是动态的,因此可以或多或少地进行更改
请帮助我使用Decodable和Codable解析它们。
所有数据都应在单个模型内。
{ "provider_code": "AIIN", "name": "Jio India", "regions": [ { "IN-WB": "West Bengal" }, { "IN-DL": "Delhi NCR" }, { "IN-TN": "Tamil Nadu" }, { "IN": "India" } ] }
答案 0 :(得分:1)
只需对区域使用字典。
struct Locations: Codable {
let providerCode: String
let name: String
let regions: [[String: String]]
enum CodingKeys: String, CodingKey {
case providerCode = "provider_code"
case name, regions
}
}
您将无法创建区域的特定模型,因为您将不知道属性名称
答案 1 :(得分:0)
一种可能的方法,不使用字典。但是我们仍然必须首先找到密钥)
我喜欢这种风格,因为我们可以从一开始就使用Regions。
// example data.
let string = "{\"provider_code\":\"AIIN\",\"name\":\"Jio India\",\"regions\":[{\"IN-WB\":\"West Bengal\"},{\"IN-DL\":\"Delhi NCR\"},{\"IN-TN\":\"Tamil Nadu\"},{\"IN\":\"India\"}]}"
let data = string.data(using: .utf8)!
// little helper
struct DynamicGlobalKey: CodingKey {
var stringValue: String
init?(stringValue: String) {
self.stringValue = stringValue
}
var intValue: Int? { return nil }
init?(intValue: Int) { return nil }
}
// model
struct Location: Decodable {
let providerCode: String
let name: String
let regions: [Region]
}
extension Location {
struct Region: Decodable {
let key: String
let name: String
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: DynamicGlobalKey.self)
key = container.allKeys.first!.stringValue
name = try container.decode(String.self, forKey: container.allKeys.first!)
}
}
}
// example of decoding.
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let location = try decoder.decode(Location.self, from: data)