Week two of coding is done. This past week was brutally frustrating as I tried to work my way through Swift’s Codable type. After 15 hours of Google searches, Swift Playgrounds, and countless rewrites of the same code; I finally figured out how to take my JSON response and turn it into useable information.
What I Learned
- Playgrounds is useful for quickly testing blocks of code
- Adding existing view controllers into a navigation bar is easy
- Codable is great… as long as you don’t have a lot of nested data
- URLSessions are an asynchronous process
- You can return data through a completion handler
At the end of my last update, I discussed how I was working on trying to get the JSON response from the Nutritionix API to conform to the Swift Codable protocol. After getting frustrated there, I shifted gears to focus on loading my restaurants. To fit with the design of my app, I want to display a list of restaurants in a tableview, and then allow you to see all food options at that restaurant. In order to accomplish this, I have to maintain a database of restaurant names with their unique ID’s so that I can properly fetch them from the API later.
After weighing the different options to store and use this data, I decided to stick with JSON since I would be using it for all of my API calls. I found this handy website that lets you convert a .csv file into .json file. I then uploaded the JSON file to my web server so that I can update it on the fly.
Decoding Restaurant JSON with Swift 4 Codable
As it turns out, simple JSON is really simple to decode. I opened up a new playground and pasted some of the JSON so I didn’t have to worry about fetching from a URL yet. After that, all it took was a simple struct that conformed with the Codable protocol. Once the decoding was successful, I stored the decoded data into a dictionary for easy reference in my tableview.
Functions and Completion Handlers
I knew that I wanted to keep my project clean and keep the data handler for fetching restaurants in it’s own function. As such, I had to figure out how to create a function that would return a dictionary upon completion. Here is what I came up:
I still have to go back through and do some actual error handling. However, this actually works! I called the function from my view controllers viewDidLoad and used it to build out my tableview cells which is very exciting.
Decoding Nested JSON within Nested JSON
I easily spent at least 15 hours trying to decode the JSON that the API returned. Here is an example of what the API returns:
Part of the problem was not having a good understanding of Codable. I had to rework this code to death, and look at numerous examples to finally make some headway. In the end, I worked with another developer who helped show me a clever way to accomplish this decoding. What I learned is that I could create a wrapper to decode the nested data that I really wanted.
After that, I set up everything that was needed to properly decode this data and conform to the Codable protocol.
Once I was confident that I was decoding my dummy data, I wrote a function that was very similar to the one for my restaurants. The primary difference with this function is that I can pass in a restaurant, and retrieve all of the foods at that restaurant from the API. I store the results in a dictionary of dictionaries so that I can keep track of each food’s unique nutritional data.
- Figure out if a dictionary of dictionaries is the right storage strategy for the purpose
- Rework the tableview cell design to show nutrition data for the food item in the table view
- Rework existing code to build in error handling