My First App: Week 2

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.

Next Up

  • 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