I've got a problem with decoding response data. Here is my request function
@IBAction func onGetCities(_ sender: UIButton) {
guard let url = URL(string: "http://somelink.com/city-list") else { return }
var request = URLRequest(url: url)
request.httpMethod = "GET"
let session = URLSession.shared
let task = session.dataTask(with: request) { (data, response, error) in
print(JSON(data))
guard let data = data else { return }
do{
let cities = try JSONDecoder().decode([City].self, from: data)
print(cities)
}catch{
}
}
task.resume()
}
And City struct
struct City: Decodable {
let id: Int
let city: String
}
Here is the response data, I want to decode "items"
{
"offset": 0,
"limit": 10,
"items": [
{id: 0, name: "City name"},
{id: 1, name: "City name1"},
.....
]
}
You need to have nested structures that mirror your nested JSON:
struct City: Decodable {
let id: Int
let city: String
}
struct ResponseObject: Decodable {
let items: [City]
let offset: Int
let limit: Int
}
And then:
do {
let result = try JSONDecoder().decode(ResponseObject.self, from: data)
print(result)
let cities = result.items
print(cities)
} catch {
print(error)
}
Note, in your original example, you included a JSON key, updated_at which was the date represented in number of seconds since 1970 (standard UNIX representation). So, to decode that:
struct City: Decodable {
let id: Int
let city: String
}
struct ResponseObject: Decodable {
let items: [City]
let offset: Int
let limit: Int
let code: Int
let updatedAt: Date
}
And then:
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
decoder.keyDecodingStrategy = .convertFromSnakeCase
do {
let result = try decoder.decode(ResponseObject.self, from: data)
print(result)
let cities = result.items
print(cities)
} catch {
print(error)
}
Note, when you see a somewhat abstract key name, such as items, that means that this might be a response structure used for various endpoints. In that case, we might to make this a generic:
struct ItemsResponse<T: Decodable>: Decodable {
let items: [T]
let offset: Int
let limit: Int
let code: Int
let updatedAt: Date
}
And then:
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
decoder.keyDecodingStrategy = .convertFromSnakeCase
do {
let result = try decoder.decode(ItemsResponse<City>.self, from: data)
print(result)
let cities = result.items
print(cities)
} catch {
print(error)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With