Lecture Handout
This lecture covers the second half of networking: decoding a response from the Internet.
Networking & Codable
Last week we talked about how to make HTTP requests to allow your app to communicate with the Internet. Today we'll talk about how to decode the responses and put them on the screen!
Decoding Responses from the Internet
Starting in Swift 4, there’s a protocol called Codable
that objects, structs, and enums can conform to to make them encodable and decodable from JSON
. Codable items can contain an enum for the coding keys of type String and CodingKey in order to decode the values from JSON.
We'll refer to the JSON response example from last lecture again today:
If we wanted to decode this example JSON response into a model of type Lecture
, we could create a Lecture
struct that conforms to Codable
as follows:
Notice how the names of our variables match the fields in our JSON. This is done on purpose! With Codable, the names of the variables are expected to exactly match the keys in the JSON response.
JSON Decoding
In order to decode the JSON response into the Lecture
class, we can create an instance of JSONDecoder
, and then call the decode
method to convert it from a JSON to a Lecture
object.
Note: Since the decoding can throw errors, we precede the decode
method by a try?
, which will make the lecture
constant an optional value. This means that lecture
will either contain a Lecture
item or it could be nil
.
Using Your Decoded Data: @escaping completions
Once you’ve decoded the lecture JSON as a Lecture
item, how do you use it? Since you're downloading this JSON from the Internet, it might take forever to load, and you only want to display this information on the screen once it’s ready (and possibly use a loading indicator in the meantime as the information loads). We also don’t want our application to just stall and wait until we get a response to do something else.
This is where a completion handler comes in handy. A completion handler is an argument passed into whatever networking function you make.
The completion handler will:
Take in your decoded object(s)
Pass them to the
ViewController
(or wherever you call this networking function from)Run some block of code that you write (ex: reload the view controller with the fetched data on the screen)
Back to the Lecture
class example from before. Suppose we want to make a function that makes the network call and returns to us the Lecture JSON decoded as a Lecture
item. Here’s an example of what that would look like:
This completion handler is marked as @escaping
because it can "escape" from the networking function call itself and hand it off to whoever called the function -- it doesn’t need to go through every line inside the function. Don't worry too much about what this means though!
Here, you can see that completion
is a function that takes in one argument which is of type Lecture
and has a return type of Void
. We only call completion when we know that the response succeeded and we actually have an actual Lecture
object.
Also note that here, we are using the responseData
method instead of the responseJSON
method! This is important because responseData
converts the response into a Data
object which is what JSONDecoder
needs to decode it.
Making Network Calls
It's good practice to create a NetworkManager
class with static methods for every network call your app makes, with the endpoint URLs hidden to the public (in case it’s private information!). This means that the earlier getLecture
function in the previous code snippet would be inside a class named NetworkManager
.
Then, in your ViewController (or wherever you want to make a network call from), you can make a network request and handle it appropriately. For example, if you have a variable for lecture and need to reload the data of a table view after you get lecture data from the Internet, you would do it like so:
The { lecture in ... }
is the escaping completion we defined in the NetworkManager
earlier. In this case, we get the lecture
variable only if we made the network call to the endpoint, received a success, received the JSON, and then decoded it. If (and only if) the network call succeeded, we run completion (the block of code from lines 5 through 10). This ensures that we receive the updated Lecture object only when it’s ready, so the screen isn’t frozen while the app is trying to execute all of these network request steps.
PDF Download
Last updated