簡體   English   中英

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

PS:有關可解碼 Swift Codable with dynamic keys的相關問題

任何解決方案都會很棒,在此先感謝

解析上述 JSON data必須使用的Codable模型應該是這樣的,

楷模:

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)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM