URL Sessions

SURLConnection got its start a decade ago, with the original release of Safari in 2003, as an abstraction on top of the Core Foundation / CFNetwork APIs. The name NSURLConnection actually refers to a group of the interrelated components that form the Foundation URL Loading System: NSURLRequest, NSURLResponse, NSURLProtocol, NSURLCache, NSHTTPCookieStorage, NSURLCredentialStorage, and its namesake, NSURLConnection.

NSURLRequest objects are passed to an NSURLConnection object. The delegate (conforming to the erstwhile informal and protocols) responds asynchronously as an NSURLResponse, and any associated NSData are sent from the server.

Before a request is sent to the server, the shared cache is consulted, and depending on the policy and availability, a cached response may be returned immediately and transparently. If no cached response is available, the request is made with the option to cache its response for any subsequent requests.

In the process of negotiating a request to a server, that server may issue an authentication challenge, which is either handled automatically by the shared cookie or credential storage, or by the connection delegate. Outgoing requests could also be intercepted by a registered NSURLProtocol object to seamlessly change loading behavior as necessary.

For better or worse, NSURLConnection has served as the networking infrastructure for hundreds of thousands of Cocoa and Cocoa Touch applications and has held up rather well, considering. But over the years, emerging use cases–on the iPhone and iPad, especially–have challenged several core assumptions, and created cause for refactoring.

At WWDC 2013, Apple unveiled the successor to NSURLConnection:

Like NSURLConnection, NSURLSession refers to a group of interdependent classes, in addition to the eponymous class NSURLSession. NSURLSession is comprised of the same pieces as before, with NSURLRequest, NSURLCache, and the like, but replaces NSURLConnection with NSURLSession, NSURLSessionConfiguration, and three subclasses of NSURLSessionTask: NSURLSessionDataTask, NSURLSessionUploadTask, and NSURLSessionDownloadTask.

The most immediate improvement NSURLSession provides over NSURLConnection is the ability to configure per-session cache, protocol, cookie, and credential policies, rather than sharing them across the app.

This allows the networking infrastructure of frameworks and parts of the app to operate independently, without interfering with one another. Each NSURLSession object is initialized with an NSURLSessionConfiguration, which specifies these policies, as well as a number of new options specifically added to improve performance on mobile devices.

The other big part of NSURLSession is session tasks, which handle the loading of data, as well as uploading and downloading files and data between the client and server. NSURLSessionTask is most analogous to NSURLConnection in that it is responsible for loading data, with the main difference being that tasks share the common delegate of their parent NSURLSession.

NSURLSessionTask :

NSURLSessionTask is an abstract subclass, with three concrete subclasses that are used directly: NSURLSessionDataTask, NSURLSessionUploadTask, and NSURLSessionDownloadTask. These three classes encapsulate the three essential networking tasks of modern applications: fetching data, such as JSON or XML, and uploading and downloading files.

When an NSURLSessionDataTask finishes, it has associated data, whereas an NSURLSessionDownloadTask finishes with a temporary file path for the downloaded file. NSURLSessionUploadTask inherits from NSURLSessionDataTask since the server response of an upload often has associated data.  All tasks are cancelable and can be paused and resumed. When a download task is canceled, it has the option to create resume data, which can then be passed when creating a new download task to pick up where it left off.

Example Syntax:

NSURLConnection added the method sendAsynchronousRequest:queue:completionHandler:, which greatly simplified its use for one-off requests, and offered an asynchronous alternative to -sendSynchronousRequest:returningResponse:error::

                         NSURL *URL = [NSURL URLWithString:@"http://example.com"];
                         NSURLRequest *request = [NSURLRequest requestWithURL:URL];

                         [NSURLConnection sendAsynchronousRequest:request
                         queue:[NSOperationQueue mainQueue]
                         completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                           // ...
                            }];

NSURLSession iterates on this pattern with its task constructor methods. Rather than running immediately, the task object is returned to allow for further configuration before being kicked off with -resume. Data tasks can be created with either an NSURL or NSURLRequest (the former being a shortcut for a standard GET request to that URL):

                          SELECT ALL NSURL *URL = [NSURL URLWithString:@"http://example.com"];
                          NSURLRequest *request = [NSURLRequest requestWithURL:URL];
                          NSURLSession *session = [NSURLSession sharedSession];
                          NSURLSessionDataTask *task = [session dataTaskWithRequest:request
                          completionHandler:
                          ^(NSData *data, NSURLResponse *response, NSError *error) {
                           // ...
                           }];

Upload Task :

Upload tasks can also be created with a request and either an NSData object or a URL to a local file to upload:

                             NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"];
                             NSURLRequest *request = [NSURLRequest requestWithURL:URL];
                             NSData *data = ...;

                             NSURLSession *session = [NSURLSession sharedSession];
                             NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request
                             fromData:data   completionHandler:
                             ^(NSData *data, NSURLResponse *response, NSError *error) {
                             // ...
                             }];

Download requests take a request as well but differ in their completionHandler. Rather than being returned all at once upon completion, as data and upload tasks, download tasks have their data written to a local temp file. It’s the responsibility of the completion handler to move the file from its temporary location to a permanent location.

                                NSURL *URL = [NSURL URLWithString:@"http://example.com/file.zip"];
                                NSURLRequest *request = [NSURLRequest requestWithURL:URL];

                                NSURLSession *session = [NSURLSession sharedSession];
                                NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request
                                completionHandler:
                                ^(NSURL *location, NSURLResponse *response, NSError *error) {
                                NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
                                NSURL *documentsDirectoryURL = [NSURL fileURLWithPath:documentsPath];
                                NSURL *documentURL = [documentsDirectoryURL URLByAppendingPathComponent:[response 
                                           suggestedFilename]];
                                [[NSFileManager defaultManager] moveItemAtURL:location
                                toURL:documentURL
                                        error:nil];
                                  }];

NSURLSession & NSURLConnection Delegate Methods :

Overall, the delegate methods of NSURLSession are a marked improvement over the rather ad-hoc pattern that emerged over the decade of NSURLConnection’s evolution. For a complete overview, check out this mapping table.

A few specific observations:

NSURLSession has both session and task delegate methods for handling authentication challenge. The session delegate method handles connection level concerns, such as Server Trust and Client Certificate evaluation, NTLM, and Kerberos, while the task delegate handles request-based challenges, such as Basic, Digest, or Proxy authentication.

Whereas NSURLConnection has two methods that signal that a request has finished (NSURLConnectionDataDelegate -connectionDidFinishLoading: and NSURLConnectionDelegate -connection:didFailWithError:), there is a single delegate method for NSURLSession (NSURLSessionTaskDelegate -URLSession:task:didCompleteWithError:) Delegate methods signaling the transfer of a certain number of bytes use parameters with the int64_t type in NSURLSession, as compared to long used by NSURLConnection.

NSURLSessionConfiguration

NSURLSessionConfiguration objects are used to initialize NSURLSessionobjects. Expanding on the options available on the request level with NSMutableURLRequest, NSURLSessionConfiguration provides a considerable amount of control and flexibility on how a session makes requests. From network access properties to the cookie, security, and caching policies, as well as custom protocols, launch event settings, and several new properties for mobile optimization, you’ll find what you’re looking for with NSURLSessionConfiguration.

Sessions copy their configuration on initialization, and though NSURLSession has a read-only configuration property, changes made on that object have no effect on the policies of the session. Configuration is read once on initialization and set in stone after that.


Author: Srinivasa Rao Polisetty – iOS Developer
Source: Wikipedia and developer.apple.com