Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
When I do an API call and get data back it cannot be decoded into my struct properly.
The error I get is:
failed to convert valueNotFound(Swift.Int, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "newDeathsByDeathDate", intValue: nil)], debugDescription: "Expected Int value but found null instead.", underlyingError: nil))
My Code is:
override func viewDidLoad() {
super.viewDidLoad()
let url = """
https://api.coronavirus.data.gov.uk/v1/data?filters=areaType=nation;areaName=england&structure=%7b%22date%22:%22date%22,%22areaName%22:%22areaName%22,%22areaCode%22:%22areaCode%22,%22newCasesByPublishDate%22:%22newCasesByPublishDate%22,%22cumCasesByPublishDate%22:%22cumCasesByPublishDate%22,%22newDeathsByDeathDate%22:%22newDeathsByDeathDate%22,%22cumDeathsByDeathDate%22:%22cumDeathsByDeathDate%22%7d
print(url)
print(NSURL(string: url))
getData(from: url)
// Do any additional setup after loading the view.
private func getData(from url: String) {
guard let theURL = URL(string: url) else { print ("oops"); return }
let getfromurl = URLSession.shared.dataTask(with: theURL, completionHandler: {data, response, error in
guard let data = data, error == nil else{
print("Something Went Wrong")
return
//Have data
var result: Response?
result = try JSONDecoder().decode(Response.self, from: data)
catch{
print("failed to convert \(error)")
guard let json = result else {
return
print(json.data)
getfromurl.resume()
My Structs are:
struct Response: Codable {
let data: [MyData]
struct MyData: Codable{
let date: String
let areaName: String
let areaCode: String
let newCasesByPublishDate: Int
let cumCasesByPublishDate: Int
let newDeathsByDeathDate: Int
let cumDeathsByDeathDate: Int
–
Please look closely at the JSON, the values for keys newDeathsByDeathDate
and cumDeathsByDeathDate
can be null
.
Make the type of the corresponding struct members optional
struct MyData: Codable{
let date: String
let areaName: String
let areaCode: String
let newCasesByPublishDate: Int
let cumCasesByPublishDate: Int?
let newDeathsByDeathDate: Int?
let cumDeathsByDeathDate: Int?
Alternatively – to keep non-optional values – decode the JSON manually and set the values to 0 if they are null
struct MyData : Decodable {
let date, areaName, areaCode: String
let newCasesByPublishDate, cumCasesByPublishDate : Int
let newDeathsByDeathDate, cumDeathsByDeathDate: Int
private enum CodingKeys : String, CodingKey { case date, areaName, areaCode, newCasesByPublishDate, cumCasesByPublishDate, newDeathsByDeathDate, cumDeathsByDeathDate }
init(from decoder : Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
date = try container.decode(String.self, forKey: .date)
areaName = try container.decode(String.self, forKey: .areaName)
areaCode = try container.decode(String.self, forKey: .areaCode)
newCasesByPublishDate = (try? container.decode(Int.self, forKey: .newCasesByPublishDate)) ?? 0
cumCasesByPublishDate = (try? container.decode(Int.self, forKey: .cumCasesByPublishDate)) ?? 0
newDeathsByDeathDate = (try? container.decode(Int.self, forKey: .newDeathsByDeathDate)) ?? 0
cumDeathsByDeathDate = (try? container.decode(Int.self, forKey: .cumDeathsByDeathDate)) ?? 0
And again, don't ignore useful error messages by printing something meaningless
Replace
print("Something Went Wrong")
print("An error occured:", error!)
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.