# Lecture Handout

## 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.&#x20;

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](http://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.&#x20;

![](/files/-M-D62T5JXJNlL9XeWZE)

### Making an HTTP Request

In this class, we’ll be using Alamofire, a [cocoapod](/resources/archived-past-semesters/sp23/chapters/6.-networking-i-and-cocoapods/lecture-handout.md#cocoapods), 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.

```swift
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.&#x20;

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”.&#x20;

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:&#x20;

```swift
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](https://stackoverflow.com/questions/43282281/how-to-add-alamofire-url-parameters?utm_medium=organic\&utm_source=google_rich_qa\&utm_campaign=google_rich_qa).

### 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.&#x20;

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

```http
{
  "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>.&#x20;

*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](https://app.gitbook.com/@cuappdev/s/intro-to-ios-development/~/drafts/-M-C8U6jPLzJef9CRm7Z/chapters/7.-networking-ii-and-codable/lecture-handout)!

## CocoaPods&#x20;

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?&#x20;

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? &#x20;

* A dependency just refers to a library, or code, that someone else has written and made public for others to use.&#x20;
* 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.&#x20;

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

{% content-ref url="/pages/-MPQ-6\_frIU-fpP6A7Hc" %}
[Setting Up CocoaPods](/resources/archived-past-semesters/sp23/cheat-sheets/setting-up-cocoapods.md)
{% endcontent-ref %}

## PDF Download

{% file src="/files/-M-DHYsjbMA8EN1MRq-r" %}
Networking I & CocoaPods
{% endfile %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ios-course.cornellappdev.com/resources/archived-past-semesters/sp23/chapters/6.-networking-i-and-cocoapods/lecture-handout.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
