Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does NSURLSession for HTTP data task (NSURLSessionDataTask) runs in background thread or we will have to provide the queue?

I started to use NSURLSession by avoiding NSURLConnection now a days as it's a new and elegant API provided by Apple. Previously, I used to put call NSURLRequest in GCD block to execute it in background. Here is how I used to do in past:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSURL *url = [NSURL URLWithString:@"www.stackoverflow.com"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLResponse *response;
    NSError *error;
    NSData *data = [NSURLConnection sendSynchronousRequest:request 
                                         returningResponse:&response 
                                                     error:&error];
    if (error) {
        // Handle error
        return;
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        // Do something with the data
    });
});

Now, here is how I use NSURLSession:

- (void)viewDidLoad 
{
    [super viewDidLoad];
 
    /*-----------------*
        NSURLSession
     *-----------------*/

    NSURL *url = [NSURL URLWithString:@"https://itunes.apple.com/search?term=apple&media=software"];

    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) 
    {
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data 
                                                             options:0
                                                               error:nil];
        NSLog(@"%@", json);
    }];
}

I want to know that, will my request be executed on background thread itself or I will have to provide my own mechanism same way I did in case of NSURLRequest ?

like image 662
NSPratik Avatar asked Jul 31 '15 12:07

NSPratik


1 Answers

No, you don't need to use GCD to dispatch this to background queue. In fact, because the completion block runs on background thread, the exact opposite is true, that if you need anything in that block to run on the main queue (e.g., synchronized updates to model objects, UI updates, etc.), you have to manually dispatch that to the main queue yourself. For example, let's imagine that you were going to retrieve a list of results and update the UI to reflect this, you might see something like:

- (void)viewDidLoad 
{
    [super viewDidLoad];

    NSURLSession *session = [NSURLSession sharedSession];

    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"https://itunes.apple.com/search?term=apple&media=software"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        // this runs on background thread

        NSError *error;
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];

        // detect and handle errors here

        // otherwise proceed with updating model and UI

        dispatch_async(dispatch_get_main_queue(), ^{
            self.searchResults = json[@"results"];    // update model objects on main thread
            [self.tableView reloadData];              // also update UI on main thread
        });

        NSLog(@"%@", json);
    }];

    [dataTask resume];
}
like image 190
Rob Avatar answered Sep 23 '22 03:09

Rob