Lesson 015 – The Basics of REST API Request/Response

RestSo far, all of our interactions in Swift have taken place locally. That is to say that we either operate fully in a Playground or we include everything that we need in our iOS application. We included images in Lesson 013 and Lesson 014, but they were included in the project, not downloaded from the Internet. Today, we are going to take our first look at using Swift to communicate with the “outside world”.

Getting Started

In order to demonstrate our lesson today, I’m just going to make a new Playground. I’m going to call it REST API Basics. There are 3rd party open source libraries that will help you do some of the things that we are going to do today. However, to make sure we are covering all of our bases, I’m going to only work with what Apple gives us right out of the box.

We are going to cover only one kind of HTTP Request today, a GET request. A GET request is what you do when you type a URL into your browser and request a web page. GET requests are very easy to test without any other tools at your disposal. You can just paste your URL into your web browser and see what you get back.

To get started, we are going to be using a freely available REST API at http://jsonplaceholder.typicode.com/. If you enter one of their example URL routes in your browser (like http://jsonplaceholder.typicode.com/posts/1) in your browser, you’ll get back some JavaScript Object Notation (JSON) that looks something like this:

Because we can see the returned data in the browser, it gives us something to check against to make sure we are handling this correctly in Swift.

Our First Request

The first thing we need to do is start with a new Playground and include these lines at the top.

The first line imports UIKit, which we need in order to make our calls. The second and third line are only important in the Playground. Playgrounds typically execute top to bottom and then stop. However, in this case, we need the Playground to still be active to handle the callback. Because we don’t want to make our application lock up and because the Internet is unpredictable, we need to make our request and then wait to hear back. We don’t wait and lock up the system, we just tell Swift where to let us know when it gets an answer. In Playgrounds, if execution has stopped (because we hit the end of code), nothing will be listening when we get our answer back. Allowing needsIndefiniteExecution to be true means that the Playground will continue to execute, which allows us to be around for our call back.

Unfortunately, due to Swift’s “safety”, handling this sort of thing is a bit more painful than it needs to be in other languages. There are third party libraries that make this easier for us, but we are going to learn the hard way first.

Our first three lines should look like this

The first line is just a string constant representing the URL we will be contacting. The second line creates a NSMutableURLRequest to that URL, but doesn’t execute it yet. The third line creates a session for these requests to operate within. This allows our requests to function more like your browser, so the web servers know that we are the same person in multiple requests using the same shared session.

The next thing we need to do is to add this outline

So, we use our shared session to create a data task from our request. We pass in the request and then we pass in an anonymous function as the completion handler. The completion handler is that “callback” that I referred to earlier. We are passed the data, the response, and an error object and we aren’t expected to return anything. This does not actually execute the task, it merely kind of “prepares” it. The subsequent line task.resume() is what actually kicks the task off.

Parsing the Data

If we want to begin to parse the data, we have to do something like the following code

The data returned is an optional and could not be there. So, we have to use the if…let syntax that we covered back in Lesson 009. If it fails to unwrap the optional, we fall to the else condition. You can test that by changing the URL to an invalid URL (I changed it from typicode.com to typicodeooo.com). When you do that, execution falls to the else block and the program prints out “We didn’t get back data”.

If it does unwrap the data object, we can attempt to parse it. We need an NSJSONReadingOptions object because it is required when we attempt to deserialize our response. Some methods allow you to pass nil when you don’t expect to use the parameter, but this one does not. Next, we call NSJSONSerialization.JSONObjectWithData, providing our unwrapped data object and our options. We will talk about why the try! is there in the next lesson, but the short version is that this method could throw an exception and we have to let Swift know that we are aware of this. Just blindly executing try! is not a best practice, and we will use this example as we demonstrate exceptions in our next lesson.

Finally, we just print out the parsed value. You should see this, which matches up with what we saw in the browser (though the properties are in a different order).

Let’s take a look at parsing this out.

I changed the assignment to jsonArray to force a conversion to a Dictionary by adding as! [String:AnyObject] at the end of the line. That then allowed me to use the ability to do multiple assignment in an if…let statement to assign all four variables and then just print them back out.

Conclusion

This is just the tip of the iceberg when dealing with making web requests from Swift. We’ve looked at essentially only the happy path, ignored other types of HTTP Requests (POST, PUT, DELETE), ignored a few safety measures, and bulldozed our way through. Over the next few lessons, we’ll deal with each of those issues in more detail as we expand our understanding. Remember, you can find the code for the lessons on GitHub.

Add Comment

Required fields are marked *. Your email address will not be published.