Swift 可编码以使用动态键解析 JSON
Swift Codable to parse JSON with dynamic keys
我正在尝试解析下面的 JSON 响应,它有多个动态键,
{
"Nagaland": {
"districtData": {
"Dimapur": {
"confirmed": 1,
"lastupdatedtime": "",
"delta": {
"confirmed": 0
}
}
}
},
"Meghalaya": {
"districtData": {
"East Khasi Hills": {
"confirmed": 1,
"lastupdatedtime": "",
"delta": {
"confirmed": 0
}
}
}
}
}
我已经像下面这样编写了我的 Codable 结构,
struct IndianStateListModel: Codable {
// MARK: Properties
let state: [String: StateData]
}
struct StateData: Codable {
// MARK: Properties
var districtData: Inner?
/// Mapping Key Enum
private enum CodingKeys: String, CodingKey {
case districtData
}
}
struct Inner: Codable {
// MARK: Properties
let districts: [String: DistrictData]
}
struct DistrictData: Codable {
// MARK: Properties
var confirmed: Int?
var lastupdatedtime: String?
var delta: DailyConfirmedData?
/// Mapping Key Enum
private enum CodingKeys: String, CodingKey {
case confirmed, lastupdatedtime, delta
}
}
struct DailyConfirmedData: Codable {
// MARK: Properties
var confirmed: Int?
/// Mapping Key Enum
private enum CodingKeys: String, CodingKey {
case confirmed
}
}
它被称为,
let summary = try JSONDecoder().decode(IndianStateListModel.self, from: data)
但它返回 nil
P.S.: 有关可解码的相关问题 Swift Codable with dynamic keys
任何解决方案都很好,提前致谢
Codable
解析上述JSONdata
的模型应该是这样的,
型号:
struct StateData: Codable {
var districtData: [String:DistrictData]?
}
struct DistrictData: Codable {
var confirmed: Int?
var lastupdatedtime: String?
var delta: DailyConfirmedData?
}
struct DailyConfirmedData: Codable {
var confirmed: Int?
}
解析:
let summary = try JSONDecoder().decode([String:StateData].self, from: data)
注意: 如果 JSON 键与 Codable
类型的属性完全匹配,则无需显式创建 enum CodingKeys
。
根本问题是 IndianStateListModel
有一个名为 states
的 属性。但是你的 JSON 中没有这样的键。我建议用 singleValueContainer
解析它。例如。也许:
struct States: Decodable {
typealias StateName = String
let states: [StateName: Districts]
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
states = try container.decode([StateName: Districts].self)
}
}
struct Districts: Decodable {
typealias DistrictName = String
var districts: [DistrictName: DistrictData]
enum CodingKeys: String, CodingKey {
case districts = "districtData"
}
}
struct DistrictData: Decodable {
var confirmed: Int
var lastupdatedtime: String
var delta: DailyConfirmedData
}
struct DailyConfirmedData: Decodable {
var confirmed: Int?
}
和
do {
let result = try JSONDecoder().decode(States.self, from: data)
print(result)
} catch {
print(error)
}
我正在尝试解析下面的 JSON 响应,它有多个动态键,
{
"Nagaland": {
"districtData": {
"Dimapur": {
"confirmed": 1,
"lastupdatedtime": "",
"delta": {
"confirmed": 0
}
}
}
},
"Meghalaya": {
"districtData": {
"East Khasi Hills": {
"confirmed": 1,
"lastupdatedtime": "",
"delta": {
"confirmed": 0
}
}
}
}
}
我已经像下面这样编写了我的 Codable 结构,
struct IndianStateListModel: Codable {
// MARK: Properties
let state: [String: StateData]
}
struct StateData: Codable {
// MARK: Properties
var districtData: Inner?
/// Mapping Key Enum
private enum CodingKeys: String, CodingKey {
case districtData
}
}
struct Inner: Codable {
// MARK: Properties
let districts: [String: DistrictData]
}
struct DistrictData: Codable {
// MARK: Properties
var confirmed: Int?
var lastupdatedtime: String?
var delta: DailyConfirmedData?
/// Mapping Key Enum
private enum CodingKeys: String, CodingKey {
case confirmed, lastupdatedtime, delta
}
}
struct DailyConfirmedData: Codable {
// MARK: Properties
var confirmed: Int?
/// Mapping Key Enum
private enum CodingKeys: String, CodingKey {
case confirmed
}
}
它被称为,
let summary = try JSONDecoder().decode(IndianStateListModel.self, from: data)
但它返回 nil
P.S.: 有关可解码的相关问题 Swift Codable with dynamic keys
任何解决方案都很好,提前致谢
Codable
解析上述JSONdata
的模型应该是这样的,
型号:
struct StateData: Codable {
var districtData: [String:DistrictData]?
}
struct DistrictData: Codable {
var confirmed: Int?
var lastupdatedtime: String?
var delta: DailyConfirmedData?
}
struct DailyConfirmedData: Codable {
var confirmed: Int?
}
解析:
let summary = try JSONDecoder().decode([String:StateData].self, from: data)
注意: 如果 JSON 键与 Codable
类型的属性完全匹配,则无需显式创建 enum CodingKeys
。
根本问题是 IndianStateListModel
有一个名为 states
的 属性。但是你的 JSON 中没有这样的键。我建议用 singleValueContainer
解析它。例如。也许:
struct States: Decodable {
typealias StateName = String
let states: [StateName: Districts]
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
states = try container.decode([StateName: Districts].self)
}
}
struct Districts: Decodable {
typealias DistrictName = String
var districts: [DistrictName: DistrictData]
enum CodingKeys: String, CodingKey {
case districts = "districtData"
}
}
struct DistrictData: Decodable {
var confirmed: Int
var lastupdatedtime: String
var delta: DailyConfirmedData
}
struct DailyConfirmedData: Decodable {
var confirmed: Int?
}
和
do {
let result = try JSONDecoder().decode(States.self, from: data)
print(result)
} catch {
print(error)
}