Scratching the surface of NSURLSession

NSURLSession is the replacement of NURLConnection, which resolves the issues occurring with the latter.

Session objects are created with the class methods which takes the configuration object.

There are 3 types of possible sessions:
  1. Default
  2. Ephemeral, in-process session
  3. Background session

NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];

The above configuration object has properties which controls the way it behaves, for instance, whether the cookies are allowed, timeouts etc.

And also few more properties like :
* allowsCellularAccess : Could be set to say the operating system whether the device is permitted to run the networking session when the cellular network is available.
* discretionary : Could be set to say the operating system to run the networking session when the device is connected to Wifi or has good power.

After creating the session configuration object, we can create the session object by passing that as follows :

URLSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];

Setting our class as delegate, we need to implement corresponding delegate methods, which notifies us with the process of data transfers.

Data transfers are encapsulated in tasks, which are of three types:
  1. Data task (NSURLSessionDataTask)
  2. Upload task (NSURLSessionUploadTask)
  3. Download task (NSURLSessionDownloadTask)

To perform a transfer with the session, we need to create a task for that, for example to download a file, the NSURLSessionDownloadTask object must be created like below :

NSString *url = @"file url here";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];

NSURLSessionDownloadTask *downloadTask = [inProcessSession downloadTaskWithRequest:request];
[downloadTask resume];


As soon as the "resume" method is called, the session starts downloading the file from the provided URL asynchronously.
And to get the progress of that downloading process, you need to implement the delegate methods of the NSURLSessionDownloadTask protocol.

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location

The above delegate is called when the file is downloaded providing you with the file download location url, the task and the session objects.
You can save your file to the documents directory or do anything with the downloaded file by accessing with the location url.

So, the above delegate gets called only if the file is downloaded successfully.
whereas this delegate method of "NSURLSessionDelegate" protocol

- (void)URLSession:(NSURLSession *)session
              task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error

gets called when each task in the session gets finished irrespective of its success or failure.

You can also track the download progress of the file through this delegate method :

- (void)URLSession:(NSURLSession *)session
      downloadTask:(NSURLSessionDownloadTask *)downloadTask
      didWriteData:(int64_t)bytesWritten
      BytesWritten:(int64_t)totalBytesWritten
      totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite

Also, the interesting stuff in NSURLSession is that you can even cancel or resume a download of the file by just calling the "cancel" or "resume" method of the tasks respectively.

For Example, you can cancel the download task as :
[downloadTask cancel];

When you cancel(Alternate "cancel" method) a task by the following method :
- (void)cancelByProducingResumeData:(void (^)(NSData *resumeData))completionHandler;

a partial NSData object is given to you, which contains the bytes downloaded so far and you can use this NSData object to resume a download, if and only if your server supports the download resuming.

You can resume the download like below :
downloadTask = [URLSession downloadTaskWithResumeData: resumeData /* partiallyDownloadedObject */];

Above are all the easiness that NSURLSession provides.


Background Download :

Just like the Default configuration, you can create a background config objects like below :

NSURLSessionConfiguration *bgConfig = [NSURLSessionConfiguration backgroundSessionConfiguration:@"Unique Identifier"];
        NSURSession *BGSession = [NSURLSession sessionWithConfiguration:bgConfig delegate:self delegateQueue:nil];

and you can use the same methods to request the server as you did for the default one.

Whereas, you need to implement :
- (void)application:(UIApplication *)application
handleEventsForBackgroundURLSession:(NSString *)identifier
                  completionHandler:(void (^)())completionHandler

in the appDelegate of the project, which activates/restarts and informs your app when the download completes and passes the payload.

So, when the app is relaunched the same NSURLSessionDownloadTask  delegates are called informing the download of the file and  you can handle it from there as usual like saving the file to the documents directory and also you need to remove and invoke the completion handler, which tells the OS that we're done with handling the downloaded file.

Conclusion :


NSURLSession provides us with the sophistication of handling the network requests with the newly added methods and still there's a lot more that could be done with this.

Comments

Popular posts from this blog

Free Hand Drawing on Google's Map View

Android from iOS Guy's Perspective

Free Hand Drawing on Maps with MapBox SDK