Tuesday, March 24, 2015

Simple NSURLConnection vs NSURLSession example - using Swift

This is a simple example of how to achieve the same simple GET call with (the "old") NSURLConnection and the new NSURLSession.

This project is now on Swift!
(so 50% less code, and 200% more "Why??"s)

This blog post is almost identical to the previous one I made on objective-c (link) but obviously written on swift. The logic and approach are the same.

The final result
This a simple app with 2 buttons, 1 label and 1 UIImageView.




When you tap the "NSURLConnection" the app downloads a picture of a car using NSURLConnection.
When you tap the "NSURLSession" the app downloads a picture of a car using NSURLSession.
The label also updates to tell you which one you're using.

NSURLConnection

Here's the code to get this GET call using NSURLConnection:
@IBAction func button_useNSURLConnection(sender: AnyObject)
{
    let url = NSURL(string: URL_CAR_1)
    var request = NSMutableURLRequest(URL: url!)
    request.HTTPMethod = "GET"
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))
        {
            var responseError: NSError?
            var data = NSURLConnection.sendSynchronousRequest(request,
                returningResponse: AutoreleasingUnsafeMutablePointer<NSURLResponse?>(),
                error: &responseError)
            
            dispatch_async(dispatch_get_main_queue(),
                {
                    self.label_status.text = "Selected NSURLConnection"
                    self.imageView.image = UIImage(data: data!)
                })
        }
}//end button_useNSURLConnection

I decided to make the NSURLConnection a Synchronous request so it can return a value (Asynchronous would just give me a value in a easier way, but that's not fun), but this means it runs in the main thread.
  1. We get a URL from a String (a constant I have defined in my class)
  2. We make a MutableURLRequest with the url of step 1
  3. Set the HTTP method of the request to GET, although this isn't really needed but its good for the tutorial to show how to set the HTTPMethod
  4. Created and used a new GCD queue to make the actual NSURLConnection in a different/background thread
  5. Once the background thread is completed, I'm calling the main GCD queue (main/UI thread) to place the downloaded image into the imageView

NSURLSession

NSURLSession is a bit different. An NSURLSession has be created with a NSURLSessionConfiguration first. Because of this I created a helper method that generates a NSURLSession with the configuration needed, and it returns the NSURLSession it creates:
func getURLSession() -> NSURLSession
{
    var session:NSURLSession
    
    var configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
    session = NSURLSession(configuration: configuration)
   
    return session;
}//end getURLSession

Since I don't want slow down the main thread for this, I placed this code in a different thread.
Then, here's how to make the NSURLSession call:
@IBAction func button_useNSURLSession(sender: AnyObject)
{
    let url = NSURL(string: URL_CAR_2)
    var request = NSMutableURLRequest(URL: url!)
    request.HTTPMethod = "GET"
    
    var task = getURLSession().dataTaskWithRequest(request)
        { (data, response, error) -> Void in
            
            dispatch_async(dispatch_get_main_queue(),
                {
                    self.label_status.text = "Selected NSURLSession"
                    self.imageView.image = UIImage(data: data!)
                })
        }
    
    task.resume()
}//end button_useNSURLSession

Very similar to the NSURLConnection, so I'll start at the NSURLSessionDataTask.
Technically, NSURLSession does not replace NSURLConnection, but NSURLSessionDataTask is what replaces NSURLConnection.

  1. NSURLSessionDataTask is an Asynchronous task, so we're kind of forced to get the data from its completion handler
  2. Call the main/UI thread and set the value of the imageView with the data from the completion handler
  3. Set the task to [task resume] so it can start
That's all!

The sample code can be found here.


Eduardo.

1 comment: