This project is in Objective-C.
Update: I just finished the exact same tutorial using swift (link)
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)button_useNSURLConnection:(id)sender { label_status.text = @"Selected NSURLConnection"; NSURL *url = [NSURL URLWithString:URL_CAR_1]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPMethod:@"GET"]; dispatch_queue_t loadQ = dispatch_queue_create("DownloadQueue", NULL); dispatch_sync(loadQ, ^{ NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; dispatch_async(dispatch_get_main_queue(), ^{ imageView.image = [UIImage imageWithData:data]; }); }); }
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
- Created a new GCD queue
- Used the 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:- (NSURLSession *)getURLSession { static NSURLSession *session = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; session = [NSURLSession sessionWithConfiguration:configuration]; }); return session; }
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)button_useNSURLSession:(id)sender { label_status.text = @"Selected NSURLSession"; NSURL *url = [NSURL URLWithString:URL_CAR_2]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPMethod:@"GET"]; NSURLSessionDataTask *task = [[self getURLSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { dispatch_async(dispatch_get_main_queue(), ^{ imageView.image = [UIImage imageWithData:data]; }); }]; [task resume]; }
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.
How to send Synchronous request in session.
ReplyDelete