AFNetworking has always been one of my favorite libraries and Alamofire is just as easy to like. Since the introduction of URLSession in iOS 7 and macOS Mavericks, I have been more reluctant to include either libraries into my projects.

The reason is simple. URLSession offers an easy-to-use, modern API for networking. It offers flexibility and several features many developers have been asking for. If a project can do without another dependency, then that is something worth considering.

URLSession is the successor of NSURLConnection. For many years, NSURLConnection has been the workhorse for networking on iOS and macOS. Most developers used or created a wrapper around NSURLConnection to hide the less enjoyable aspects of the NSURLConnection interface.

In addition to being a class, URLSession is a technology that provides the infrastructure for networking, exposed through a modern and elegant API. In this series, I introduce you to the URLSession stack. You learn how easy it is to get started with URLSession and you discover that URLSession exposes a flexible API that should meet anyone's networking needs.

Meet the Family

The URLSession family includes a number of key classes. The URLSession class is the central component of the URLSession stack. It is used to create and configure network requests.

Another important class is URLSessionConfiguration. A session configuration object is used to configure a URLSession instance. The session is in charge of managing requests. The session configuration defines the behavior of the session. This is especially interesting for uploading and downloading data.

The workhorses of URLSession are URLSessionTask and its concrete subclasses. The subclasses you will interact with most are:

  • URLSessionDataTask for fetching data
  • URLSessionUploadTask for uploading data
  • URLSessionDownloadTask for downloading data

URLSessionDataTask and URLSessionDownloadTask directly inherit from URLSessionTask. URLSessionUploadTask is a subclass of URLSessionDataTask.

A URLSessionTask object is always associated with a session. You can create a URLSessionTask object by asking the session for one. This is illustrated by the following example. We discuss the details a bit later in this tutorial.

// Reference to Shared Session
let session = URLSession.shared

// Create Request
let request = URLRequest(url: url)

// Create Data Task
let dataTask = session.dataTask(with: request)

Fetching Data

Now that we have met the family, it is time to create a request to see how the various pieces fit together. Create a new project in Xcode based on the Single View Application template. Set Product Name to Networking and Language to Swift.

Project Setup

Project Setup

To illustrate how the URLSession stack works, we will fetch an image from the web and display it in an image view. This simple example will show you how easy it is to create a request, schedule it, and handle its response.

Open Main.storyboard and add an image view to the View Controller Scene. Add the required constraints to pin the image view to the edges of its superview. Open the Attributes Inspector and set Mode to Aspect Fit.

Storyboard Setup

Open ViewController.swift and create an outlet for the image view. Revisit Main.storyboard and connect the outlet to the image view.

import UIKit

class ViewController: UIViewController {

    // MARK: - Properties

    @IBOutlet var imageView: UIImageView!

    ...

}

Open ViewController.swift and update viewDidLoad() as shown below.

override func viewDidLoad() {
    super.viewDidLoad()

    // Obtain Reference to Shared Session
    let sharedSession = URLSession.shared

    if let url = URL(string: "https://goo.gl/wV9G4I") {
        // Create Request
        let request = URLRequest(url: url)

        // Create Data Task
        let dataTask = sharedSession.dataTask(with: request, completionHandler: { (data, response, error) -> Void in
            if let data = data, let image = UIImage(data: data) {
                DispatchQueue.main.async {
                    self.imageView.image = image
                }
            }
        })

        dataTask.resume()
    }
}

We obtain a reference to a URLSession instance by invoking shared on the URLSession class. This returns a shared session object, a singleton, that uses the global cache, cookie storage, and credential storage. There are other options to create a session, but the shared session is fine for this example.

We then create a URL instance and use that to create a request, an instance of the URLRequest class. To make a request, we ask the session for a data task by invoking dataTask(with:completionHandler:). This method accepts two arguments, the request and a closure. The closure accepts three arguments:

  • an optional Data instance
  • an optional URLResponse instance
  • and an optional Error instance

The closure is executed when the request completes, successfully or unsuccessfully. We use optional binding to safely unwrap the data that is returned to us and we use it to instantiate a UIImage object. We update the image view with the resulting image.

It is important to point out that we explicitly update the image view on the main thread. The closure we pass to dataTask(with:completionHandler:) is invoked on a background thread and, therefore, we are required to dispatch updating the image view to the main queue.

Last but not least, we schedule the data task by invoking resume() on the data task. This is easily overlooked. Run the application in the simulator or on a physical device to see the result.

Downloading and Displaying an Image

What's Next?

Using URLSession is much easier than NSURLConnection. It is clear Apple decided it was time to rethink networking on iOS and macOS when they created URLSession. In this tutorial, you learned about the very basics of URLSession. In the next tutorial, we take a look at the more advanced options of the URLSession API.

You can download the source files of the tutorial from GitHub.