Reputation: 1301
I'm practicing the new way of parsing JSON in Swift 4 and I'm using the New York Times API - I'm finding it hard to read the structure of the JSON since the API page just shows a wall of text
I've written out a small struct for the data I want to pull (titles, abstracts):
struct Stories: Decodable {
let title: String
let abstract: String
}
and here's the function I call to get the JSON:
func getJSON() {
let jsonUrlString = "https://api.nytimes.com/svc/topstories/v1/business.json?api-key=f4bf2ee721031a344b84b0449cfdb589:1:73741808"
guard let url = URL(string: jsonUrlString) else {return}
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else {return}
do {
let stories = try
JSONDecoder().decode(Stories.self, from: data)
print(stories.title, stories.abstract)
} catch let jsonErr {
print("Error serializing JSON", jsonErr)
}
}.resume()
}
When I run the app, I see my error message in the console:
Error serializing JSON keyNotFound(CodingKeys(stringValue: "title", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"title\", intValue: nil) (\"title\").", underlyingError: nil))
So it looks like it's not finding the values of "title". What can I do differently here, did I set up the Struct incorrectly? Or am I using JSONDecorder wrong?
Thanks for any help!
Upvotes: 0
Views: 533
Reputation: 54706
The issue is that the Stories
are nested in an outer Dictionary
, which you also need to parse.
struct TopStoriesResponse: Codable {
let status:String
let results:[Story]
}
struct Story: Codable {
let title: String
let abstract: String
}
func getTopStories() {
let jsonUrlString = "https://api.nytimes.com/svc/topstories/v1/business.json?api-key=f4bf2ee721031a344b84b0449cfdb589:1:73741808"
guard let url = URL(string: jsonUrlString) else {return}
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data, err == nil else {
print(err!)
return
}
do {
let response = try JSONDecoder().decode(TopStoriesResponse.self, from: data)
print(response.results.first?.title, response.results.first?.abstract)
} catch let jsonErr {
print("Error serializing JSON", jsonErr)
}
}.resume()
}
Upvotes: 1