Learn Courses My Dashboard

How to use JSON data after parsing it?

I’m getting data using this API: Recipe - Food - Nutrition API Documentation (spoonacular) | RapidAPI

In this example, I’m using a GET method for “Extract Recipe from Website.”’

This is what I have in my viewDidLoad():

let headers = [
            "x-rapidapi-host": "spoonacular-recipe-food-nutrition-v1.p.rapidapi.com",
            "x-rapidapi-key": "1234567890qwertyuiopasdfghjklzxcvbnm"
        ]

        let request = NSMutableURLRequest(url: NSURL(string: "https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/extract?url=http%3A%2F%2Fwww.melskitchencafe.com%2Fthe-best-fudgy-brownies%2F")! as URL,
                                                cachePolicy: .useProtocolCachePolicy,
                                            timeoutInterval: 10.0)
        request.httpMethod = "GET"
        request.allHTTPHeaderFields = headers

        let session = URLSession.shared
        
        let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
            if (error != nil) {
                print(error)
            } else {
                let httpResponse = response as? HTTPURLResponse
                
                // Parse out the data
                do {
                    let dictionary = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String:Any]
                    print("DICTIONARY: \(dictionary)")
                }
                catch {
                    print("Error parsing response data")
                }
            }
        })

        dataTask.resume()

When I view the breakpoint at print("Error parsing response data"), I can see that I’ve successfully parsed the data. For example:
Screen Shot 2021-12-11 at 5.03.28 PM

But once I’ve done that parsing, how can I actually use those key-value pairs? For example if I wanted to extract the value from the key of “id”?

Any help is much appreciated!

a) Don’t use NSMutableURLRequest, use URLRequest instead.
b) Don’t use NSURL, use URL instead.
c) Don’t use JSONSerialization, use Codable and model structs instead.

That last item is the important one for getting data out of the response. Instead of key-value pairs, you will have fully constructed structs you can use to get your data. The exact shape of those structs depends on the data you receive in response to the API call. Read up on Codable for more info.

Thank you so much @roosterboy!

I’ve implemented your recommendations and referred to the documentation:

struct Meal: Codable {
    var id: Int
    var title: String
    var readyInMinutes: Int
    var image: String
    var imageUrls: [String]
}

let headers = [
            "x-rapidapi-host": "spoonacular-recipe-food-nutrition-v1.p.rapidapi.com",
            "x-rapidapi-key": "1234567890qwertyuiopasdfghjklzxcvbnm"
        ]

        let spoonacularURL = URL(string: "https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/extract?url=http%3A%2F%2Fwww.melskitchencafe.com%2Fthe-best-fudgy-brownies%2F")
        
        var request = URLRequest(url: spoonacularURL!, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
        
        request.httpMethod = "GET"
        request.allHTTPHeaderFields = headers

        let session = URLSession.shared
        
        let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
            if (error != nil) {
                print(error)
            } else {
                let httpResponse = response as? HTTPURLResponse
                
                // Parse out the data
                do {
                    let decoder = JSONDecoder()
                    let arrayTest = try decoder.decode(Meal.self, from: data!)
                }
                catch {
                    print("Error parsing response data")
                }
            }
        })

        dataTask.resume()

However, let arrayTest = try decoder.decode(Meal.self, from: data!) is not successfully parsing as I’m getting my “Error parsing response data” print statement. I’ve also tried let arrayTest = try decoder.decode([Meal].self, from: data!).

Is there something I’m missing to parse the data?

Instead of printing out an unhelpful message like that, use print(error) to see what the actual problem is. Sorry, I should have mentioned that the first time.

Thank you so much @roosterboy. That was super helpful advice. I printed error and was able to figure out that it wasn’t parsing because imageUrls was not a valid key.