For several hours I've been trying to parse to a JSON file with an array to experiment with API's, but I keep getting errors. I managed to parse a file with just one JSON object/dictionary (following different tutorials), but I can't figure it out for a JSON file with an array of objects. I'm testing this out with a coronavirus API. Here is the URL so you can see the JSON code: https://coronavirus-19-api.herokuapp.com/countries. I feel like the solution is very simple and there's just something small that I'm missing, but I'm not really sure.
This is the error I get:
valueNotFound(Swift.Int, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 10", intValue: 10), CodingKeys(stringValue: "recovered", intValue: nil)], debugDescription: "Expected Int value but found null instead.", underlyingError: nil))
Here is my code:
import UIKit
class FirstViewController: UIViewController {
var coronaInfo = [CoronaInfo]()
override func viewDidLoad() {
super.viewDidLoad()
let url = "https://coronavirus-19-api.herokuapp.com/countries"
getData(from: url) { (data) in
self.coronaInfo = data
print(self.coronaInfo[0].cases) // <-- Works in here
}
print(coronaInfo[0].cases) // <-- Outside of the closure it's nil
}
func getData(from url: String, completed: @escaping ([CoronaInfo]) -> ()) {
URLSession.shared.dataTask(with: URL(string: url)!) { data, response, error in
// Make sure that data isn't nil and that there was no error
guard let data = data, error == nil else { print("Something went wrong"); return }
var result: [CoronaInfo]?
do {
// Convert data from bytes to the custom object (Known as JSON decoding)
result = try JSONDecoder().decode([CoronaInfo].self, from: data)
guard let json = result else { return }
DispatchQueue.main.async {
completed(json)
}
} catch { print(error) }
}.resume()
}
}
struct CoronaInfo: Codable {
let country: String
let cases: Int
let todayCases: Int
let deaths: Int
let todayDeaths: Int
let recovered: Int?
let active: Int?
let critical: Int
let casesPerOneMillion: Int
let deathsPerOneMillion: Int
let totalTests: Int
let testsPerOneMillion: Int
}
Thanks in advance for any help!
Two points worth mentioning here
let url = "https://coronavirus-19-api.herokuapp.com/countries"
getData(from: url)
struct CoronaData: Codable {
let country: String
let cases: Int
let todayCases: Int
let deaths: Int
let todayDeaths: Int
let recovered: Int?
let active: Int?
let critical: Int
let casesPerOneMillion: Int
let deathsPerOneMillion: Int
let totalTests: Int
let testsPerOneMillion: Int
}