A L A L - 3 years ago 289
JSON Question

Issue with JSON decoding in Swift (data missing)

I'm trying to query the NASA image API (latest docs here) using Swift 4. I set up and tested my request with JSONPlaceholder to make sure my network request and decoding was setup correctly. Everything was working fine, but when I switched the URL and corresponding JSON data structure, I get an error saying 'the data couldn't be read because it is missing.'

I've used Postman to verify that JSON is being returned, and to build the JSON data structure.

Is this a common error from decoding JSON or is it something with the network request? Or am I missing something with using the NASA API?

let NASAURL = URL(string: "https://images-api.nasa.gov/search?q=moon")
let session = URLSession(configuration: .default)
let task = session.dataTask(with: NASAURL!) { (rdata, response, error) in
NSLog("Data Description: " + (rdata!.debugDescription) + "\nResponse: " + response.debugDescription + "\nError Description: " + error.debugDescription)

guard rdata != nil else{
NSLog("No data")
return
}
guard error == nil else{
NSLog(response.debugDescription + "\n")
NSLog(error.debugDescription)
NSLog(error.debugDescription)
return
}
let decoder = JSONDecoder()
do{
NSLog(rdata.debugDescription)
let usr = try decoder.decode(Collect.self, from: rdata!) // Throws
NSLog(usr.href)

} catch {
NSLog("Error: " + error.localizedDescription)
}
}
task.resume()

// Collect is in its own class/file
struct Collect: Codable {
var href: String
//var items: [Items]
}


Below is the printout from the above log statements...

2017-09-29 19:50:24.135288-0500 OpenNASA[16993:10774203] Data Description: 67669 bytes
Response: Optional(<NSHTTPURLResponse: 0x60000003db00> { URL: https://images-api.nasa.gov/search?q=moon } { status code: 200, headers {
"Access-Control-Allow-Origin" = "*";
"Cache-Control" = "public, max-age=300, s-maxage=600";
"Content-Encoding" = gzip;
"Content-Length" = 9334;
"Content-Type" = "application/json; charset=UTF-8";
Date = "Sat, 30 Sep 2017 00:48:11 GMT";
Server = "nginx/1.4.6 (Ubuntu)";
"Strict-Transport-Security" = "max-age=31536000";
Vary = "Accept-Encoding";
"access-control-allow-headers" = "Origin,Content-Type,Accept,Authorization,X-Requested-With";
"access-control-allow-methods" = GET;
} })
Error Description: nil
2017-09-29 19:50:24.137324-0500 OpenNASA[16993:10774203] Optional(67669 bytes)
2017-09-29 19:56:01.843750-0500 OpenNASA[16993:10774203] Error: The data couldn’t be read because it is missing.

Answer Source

You Codable should be like below:

struct Collect: Codable {
    var collection: Links
}
struct Links: Codable {
    var links: [Href]
}

struct Href: Codable {
    var href: String
}

You have to call like below:

let usr = try decoder.decode(Collect.self, from: rdata!) // Throws
let links = usr.collection.links
for link in links {
    print(link.href)
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download