我正在尝试解码JSON字符串,但似乎有多个列表,这些列表没有可用于结构调用的任何名称/键。据我所知(我所掌握的知识很少),此JSON内部有两个列表,我只想要第二个列表。我知道如何解码普通的JSON,但弄清楚如何调用此无密钥列表/数组令人困惑。
我尝试根据自己想要的列表使结构体使用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: $0.0, value: $0.1) }
return components?.url
}
}
我真的只想最终访问日期并将它们放入tableView的数组中,并能够访问以下视图的其余JSON数据。
非常感谢你, 杰克
答案 0 :(得分:4)
您只需要在手动解码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)