如何解码在 Swift 中有多个未命名列表的 JSON

How to decode JSON that has multiple lists that are unnamed in Swift

我正在尝试解码 JSON 字符串,但似乎有多个列表没有任何 names/keys 我可以用我的结构调用。据我所知(据我所知),此 JSON 中有两个列表,我只想要第二个列表。我知道如何解码普通 JSON 但弄清楚如何调用这个无密钥 list/array 是令人困惑的。

我试图让我的结构使用 0 或 1,这取决于我想要的列表,作为案例名称,但这也不起作用。我真的只是对如何调用未明确命名的东西感到困惑。下面是我的 JSON 数据和代码。

这是JSON的一小部分:

[{
    "page": 1,
    "pages": 1,
    "per_page": "5000",
    "total": 58
  },
  [{
    "indicator": {
        "id": "NY.GDP.MKTP.CD",
        "value": "GDP (current US$)"
    },
    "country": {
        "id": "US",
        "value": "United States"
    },
    "value": "19390604000000",
    "decimal": "0",
    "date": "2017"
  },
  {
    "indicator": {
        "id": "NY.GDP.MKTP.CD",
        "value": "GDP (current US$)"
    },
    "country": {
        "id": "US",
        "value": "United States"
    },
    "value": "18624475000000",
    "decimal": "0",
    "date": "2016"
  }]
 ]

这是我的 Swift 代码:

    let url = URL(string:"https://api.worldbank.org/countries/USA/indicators/NY.GDP.MKTP.CD?per_page=5000&format=json")!

    let task = URLSession.shared.dataTask(with: url) {(data,response, error) in
        if let data = data {
            let jsonDecoder = JSONDecoder()
            let countryData = try? jsonDecoder.decode(CountryData.self, from:data)
            print(countryData?.data)
        }
    }
    task.resume()

    struct CountryData: Codable {
         let data: [Country]
         enum CodingKeys: String, CodingKey {
               case data = ""
         }
         init(from decoder: Decoder) throws {
               let valueContainer = try decoder.container(keyedBy: CodingKeys.self)
               self.data = try valueContainer.decode([Country].self, forKey: CodingKeys.data)
         }
   }

    struct Country: Codable {
          let value: String
          let date: String
          let total: String
          enum CodingKeys: String, CodingKey {
                case value = "value"
                case date = "date"
                case total = "total"
          }
          init(from decoder: Decoder) throws {
                let valueContainer = try decoder.container(keyedBy: CodingKeys.self)
                self.value = try valueContainer.decode(String.self, forKey: CodingKeys.value)
                self.date = try valueContainer.decode(String.self, forKey: CodingKeys.date)
                self.total = try valueContainer.decode(String.self, forKey: CodingKeys.total)
          }
    }

    extension URL {
          func withQueries(_ queries: [String: String]) -> URL? {
                var components = URLComponents(url: self, resolvingAgainstBaseURL: true)
                components?.queryItems = queries.compactMap
                    { URLQueryItem(name: [=13=].0, value: [=13=].1) }
                return components?.url
          }
    }

我真的只想最终访问日期并将它们放入 tableView 的数组中,并能够访问以下视图的其余 JSON 数据。

非常感谢, 杰克

手动解码 JSON 数组时,您只需使用 decoder.unkeyedContainer()。然后您可以指定要逐个解码的元素的类型,这是您需要的,因为数组的第一个和第二个元素是不同的。如果它们相同,您可以简单地使用 JSONDecoder.decode([ArrayElementType].self).

对其进行解码
struct CountryData: Decodable {
    struct Indicator: Decodable {
        let id:String
        let value:String
    }

    struct Country: Decodable {
        let id:String
        let value:String
    }

    let indicator:Indicator
    let country:Country
    let value:String
    let decimal:String
    let date:String
}

struct CountryDataResponse: Decodable {
    let countries:[CountryData]

    struct CountryDataRoot: Decodable {
        let page:Int
        let pages:Int
        let per_page:String
        let total:Int
    }

    init(from decoder:Decoder) throws {
        var container = try decoder.unkeyedContainer()
        try container.decode(CountryDataRoot.self)
        countries = try container.decode([CountryData].self)
    }
}

let countries = try JSONDecoder().decode(CountryDataResponse.self, from: yourJson)