Lecture Handout

This lecture covers the first half of networking (making a request) and introduces Cocoapods.

Networking

Making an App Communicate with the Internet: HTTP Requests

So far in this course, we’ve only dealt with hard-coded data that we’ve created ourselves to show on screen, but most apps don’t have static information. In order to have non-static data, we need a way for our app to communicate with the Internet.

HTTP requests are a method to communicate between a client (e.g. your iOS app) and a server (the Internet). HTTP requests are used all over development, and there are many different types. The most common types of requests are GET and POST requests. GET requests are used to get information from the internet (ex. Getting information from www.google.com), and POST requests are used to post information onto the internet (ex. Submitting a form). Other methods include PUT, DELETE, and more.

Making an HTTP Request

In this class, we’ll be using Alamofire, a cocoapod, to make HTTP requests. Alamofire is a Swift HTTP networking library that makes it very easy for us to make network requests, allowing us to make the requests and handle the results without worrying about setting up networking layers and manually validating results.

A GET Request

Here’s an example of making a GET request to fetch recent posts from The Cornell Daily Sun’s website. We’ll just print the data we get back.

let endpoint = "http://cornellsun.com/wp-json/wp/v2/posts"

AF.request(endpoint, method: .get).validate().responseJSON { response in
  // Depending on what response JSON we get here, we can appropriately handle it.
  switch response.result {
  // If the response is a success, print the data
  case let .success(data):
      print(data)
  // If the response is a failure, print a description of the error
  case .failure(let error):
      print(error.localizedDescription)
  }
}

Notice that here the method we’re using is responseJSON(on line 3). This method takes the response from the server and converts it into a JSON object, which we can then print out and see the response in a friendly format. Later on, when we actually decode the responses (instead of just printing them) we'll switch to using the responseData method, which converts the response into a Data object instead.

If the request is successful, the printed response will look something like this:

[{"id":3597603,"date":"2018-07-17T01:45:30","date_gmt":"2018-07-17T05:45:30",
"guid":{"rendered":"http:\/\/cornellsun.com\/?p=3597603"},
"modified":"2018-07-17T01:45:30","modified_gmt":"2018-07-17T05:45:30",
"slug":"jurassic-world-fallen-kingdom-bites-off-more-than-it-canchew",
"type":"post","link":"http:\/\/cornellsun.com\/2018\/07\/17\/jurassicworld-fallen-kingdom-bites-off-more-than-it-can-chew\/",
"title":{"rendered":"Jurassic World: Fallen Kingdom Bites Off More Than It Can Chew”},
"content":{ ... }]

A POST Request

Sometimes, you want to send information to the network instead of just receiving it. For example, when you search for something (for example, “Taylor Swift”) in iTunes, you make a network request by sending the string “Taylor Swift” to the server in a POST request.

In Alamofire, you can pass in a Parameter object with your network request to the endpoint you choose. The Parameter object is a dictionary mapping strings to strings. For example, in iTunes, the search endpoint requires four parameters: term, country, media, and entity. The search term is the keywords joined by the + sign (so “Taylor Swift” would become “Taylor+Swift”.

For example, let’s say we’re searching songs by Taylor Swift in the US, so the media type is music and the entity type is songs. Here’s what this would look like as an Alamofire network request:

private static let endpoint = "https://itunes.apple.com/search"

static func getTracks(withQuery query: String, completion: @escaping([Song]) -> Void) {
 
 let parameters: Parameters = [
   "term" : query.replacingOccurrences(of: " ", with: "+"),
   "country" : "US",
   "media" : "music",
   "entity" : "song"
 ]
 
 AF.request(endpoint, method: .post, parameters: parameters).validate().responseJSON { response in
   // handle response here
   switch response.result {
    ...
   }
 }
}

Note on Alamofire query parameters: Depending on how your endpoint receives parameters on the backend, you might need to add in another argument to your Alamofire request. For example, if your search endpoint takes in query strings, you’ll need to add the extra argument for query string parameter encoding, which is URLEncoding(destination: .queryString). If you’re having trouble with your Alamofire POST requests this most likely will fix it! For more information, see this StackOverflow post here.

Interpreting Responses from the Internet

The sample response above (in the GET request example) is formatted in JSON (JavaScript Object Notation), which is a key-value coding format commonly used in server responses. Almost all of the responses you get from the Internet will be in JSON format. Each JSON is wrapped in two curly braces { }, and data is separated by commas. Values in JSON can be strings, numbers, objects (items wrapped in curly braces), null, booleans, or arrays.

Here’s an example of a JSON response you might get:

{
  "title": "HTTP, Networking, and JSON",
  "year_created": 2020,
  "success": true,
  "topics": [ "HTTP", "Networking", "JSON" ],
}

The keys are the strings in front of the colons (e.g. title, year_created, etc), and the values are after the colons (e.g. HTTP, Networking, and JSON, 2020, etc). Note that the entire snippet is an object itself as it's wrapped between two curly braces.

Usually, the responses will be condensed into one blob of text (as seen in the previous example), so it's help to use a JSON pretty-printer to format it to make it easier to read. Here’s an example of a good JSON printer that might be useful: https://jsonformatter.org/jsonpretty-print.

So, how do you decode these responses and put them on screen? We'll talk about decoding responses from the Internet in the next lecture!

CocoaPods

When building our applications, there will come times when we want to build a very complicated UI or perform some sort of special task. In these cases, we have two options. We can try to build this new feature from scratch all by ourselves OR we can use a library that other people have already written and made public because they figured that other people would want to have this feature in their application.

What is a CocoaPod?

From the CocoaPods website: “CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. It has over 53 thousand libraries and is used in over 3 million apps.” But what does this mean?

  • A dependency just refers to a library, or code, that someone else has written and made public for others to use.

  • A dependency manager is a tool that manages all the libraries that are used in your application. To give some examples, for Python applications, the dependency manager is pip and for node.js applications, the dependency manager is npm. For Swift applications, this is Cocoapods.

In the course, we will be using CocoaPods to install and be able to use any external libraries that we want to use in our application.

Setting Up CocoaPods

pageSetting Up CocoaPods

PDF Download

Last updated