Running NSURLSession completion handler on main thread Running NSURLSession completion handler on main thread multithreading multithreading

Running NSURLSession completion handler on main thread


Yes, just dispatch your main thread stuff using GCD:

 NSURLSession *session = [NSURLSession sharedSession];    [[session dataTaskWithURL:[NSURL URLWithString:@"http://myurl"]            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {                NSError *jsonError = nil;                NSArray* jsonUsers = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];                if (jsonError) {                    NSLog(@"error is %@", [jsonError localizedDescription]);                    // Handle Error and return                    return;                }                dispatch_async(dispatch_get_main_queue(), ^{                    self.userArray = jsonUsers;                    [self.userTableView reloadData];                    if ([[NSThread currentThread] isMainThread]){                        NSLog(@"In main thread--completion handler");                    }                    else{                        NSLog(@"Not in main thread--completion handler");                    }                });            }] resume];


@graver's answer is good. Here's another way you can do it:

NSURLSession* session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]                                                          delegate:nil                                                     delegateQueue:[NSOperationQueue mainQueue]];[[session dataTaskWithURL:[NSURL URLWithString:@"http://myurl"]        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {            NSError *jsonError = nil;            NSArray* jsonUsers = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];            if (jsonError) {                NSLog(@"error is %@", [jsonError localizedDescription]);                // Handle Error and return                return;            }            self.userArray = jsonUsers;            [self.userTableView reloadData];            if ([[NSThread currentThread] isMainThread]){                NSLog(@"In main thread--completion handler");            }            else{                NSLog(@"Not in main thread--completion handler");            }        }] resume];

This way you create a session that calls the completion block and any delegate methods on the main thread. You may find this more aesthetically pleasing, but you do lose the advantage of running the "hard work" in the background.


Here is the best way to update UI from blocks and completion handler, and also when you not confrim which thread running your code.

static void runOnMainThread(void (^block)(void)){    if (!block) return;    if ( [[NSThread currentThread] isMainThread] ) {        block();    } else {        dispatch_async(dispatch_get_main_queue(), block);    }}

This is static method which will have a block, and will run on main thread, it will act like a

runOnMainThread(^{           // do things here, it will run on main thread, like updating UI        });