Introduction to NSURLSession

As part of the connected world, many apps consume content from online sources or transfer the data they produce to external repositories on the Internet.

Available since iOS2, NSURLConnection and its related classes handle URL requests and manage the data transfer using the standard Internet protocols. They encapsulate the complexity of data communication is an easy-to-use API capable to perform tasks like loading Web pages, querying Web Services and transferring files.

NSURLSession was introduced in iOS7 to add more functionality and flexibility to the data communication, thereby facilitating the implementation of particularly complex use cases. This article is an introduction to using NSURLSession in the simple use case of downloading remote files from a Web server. It is split in two parts: in the first part we’ll see how to implement a custom caching system for the downloaded resources and in the second part we’ll take advantage of the iOS background fetching feature to perform the downloads and update the UI while the app is closed.

NSURLSession basic architecture

Data communication using NSURLSession relies on a group of networking classes, each one performing specific tasks in the process. The relationships between these classes are illustrated in the next diagram:

The session parameters and policies can be set using an NSURLSessionConfiguration object. One major improvement over the old NSURLConnection is the ability to create as many URL session as needed, each one with its own configuration. If the default configuration is all that’s needed, it’s possible to skip the NSURLSessionConfiguration instantiation and directly use [NSURLSession sharedSession] to create a session adopting the global settings for NSURLCache, NSHTTPCookieStorage and NSURLCredentialStorage.

NSURLSessionConfiguration provides class methods to instantiate different types of session configurations:

  • +defaultSessionConfiguration – uses the default options
  • +ephemeralSessionConfiguration – disables caches, cookies and credentials, allowing for anonymous sessions
  • +backgroundSessionConfigurationWithIdentifier: – special set of parameters for sessions running in the background, when the app is closed.

The actual data transfer is performed by a subclass of NSURLSessionTask, which is an abstract class defining the general attributes and operations of a downloading or uploading task object.

There are three subclasses of NSURLSessionTask, one for each type of data communication:

  • NSURLSessionDataTask: for generic data transfers, commonly used to invoke remote Web Services using GET requests and retrieve the data they provide in formats like XML or JSON
  • NSURLSessionUploadTask: is a subclass of NSURLSessionDataTask allowing to perform POST and PUT requests able to encapsulate large volumes of data. It can be used to upload files to a remote server and can be run in the background
  • NSURLSessionDownloadTask: performs file download from a remote server and can be used to download large files while the app is suspended or even closed.

NSURLSession class exposes methods to create any of the previous kinds of tasks using a NSURL or NSURLRequest objet as an argument. The advantage of using NSURLRequest is the possibility to define per task parameters, like the cache policy and the timeout interval, instead of using a NSURLSessionConfiguration object to initialize the settings.

As any modern communication API, NSURLSession provides asynchronous handlers allowing to run custom code when specific events occur during the communication process. These handlers are either code blocks provided at session task creation (for instance, in the class method +dataTaskWithRequest:completionHandler) or delegate methods for the session object or the different types of session task objects.

What are we going to build?

To demonstrate how NSURLSession can be used in a real project, I’ve implemented a simple app that downloads its content from a Web server. It transfers images from the remote server using their URL, saves them locally, then displays them in a table view as thumbnails. The images metadata (title and URL) is stored in a XML file which is also downloaded from the Web server.

The data is downloaded when the app is launched. The user can also trigger the download using the well-known pull-to-refresh gesture on the table view.

The sample projet can be downloaded on here.

Custom cache

NSURLSession provides its own caching system exposed by the NSURLCache class. Theoretically, it provides memory and disk caching, exactly what we need for our example. In practice, I wasn’t able to make it work as expected and it seems to be currently broken in iOS 8.

Instead of the very seducing NSURLCache, I’ve implemented a basic custom caching system which stores in NSUserDefaults a dictionary containing the downloaded files URL and their last modification date. The NSMutableURLRequest is initialized with the file URL and the last modification date set for the “If-Modified-Since” HTTP header attribute:<

If the file wasn’t modified on the remote server since the previous request, the HTTP response status code is 304 and the file is not downloaded again, avoiding the unnecessary data transfer.

Download task

Because the standard caching system is not used and we don’t need a special authentication policy to be able to download the files from the Web server, we’re using the default configuration for the NSURLSession object created by the method [NSURLSession sharedSession].

We’re also using a NSURLSessionDownloadTask to perform the file transfer, and implement the completion handler block to update the cache if necessary and refresh the UI. Because the UI refreshing must occur asynchronously, after the HTTP request is completed, it’s performed inside the completionBlock which is invoked by the session task completion handler.

Update the User Interface

When the photo metadata transfer is finished, the table view is refreshed using a code block executed in the download task completion handler. The -reloadData method of the table view triggers the table view data source methods which reinitialize each table cell.

The custom table view cell class uses the file download method from the TransferManager class to get the image from the Web server or from the local cache, then loads the image in the thumbnail image view.

Conclusion

This article only covered the basics of NSURLSession and how it could be used to perform simple networking tasks. I hope it facilitates the approach to find solutions for more complex use cases. I also recommend using the AFNetworking framework if you need a powerful tool to handle the network communications in your iOS projects.

 

Catalin Rosioru

 

One thought on “Introduction to NSURLSession

Comments are closed.