Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running NSURLSession completion handler on main thread

I am using a NSURLSession to get the values to populate a TableView. I am updating the TableView in the completion handler, but using [[NSThread currentThread] isMainThread] has shown me that the completion handler isn't running in the main thread. Since I should only updating the UI from the main thread, I know this isn't correct. Is there a way to trigger an action on the main thread from the completion handler? Or is using a NSURLSession the wrong way to go about this?

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;             }             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]; 
like image 844
otter Avatar asked Nov 18 '13 16:11

otter


2 Answers

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]; 
like image 123
graver Avatar answered Oct 08 '22 18:10

graver


@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.

like image 44
bugloaf Avatar answered Oct 08 '22 18:10

bugloaf