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.
- We get a URL from a String (a constant I have defined in my class)
- We make a MutableURLRequest with the url of step 1
- 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
- Created and used a new GCD queue to make the actual NSURLConnection in a different/background thread
- 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.
- NSURLSessionDataTask is an Asynchronous task, so we're kind of forced to get the data from its completion handler
- Call the main/UI thread and set the value of the imageView with the data from the completion handler
- Set the task to [task resume] so it can start
The sample code can be found here.
Eduardo.
NSURLConnection is deprecated in iOS9
ReplyDelete