NSURLSessionDataTask dataTaskWithURL completion handler not getting called

匿名 (未验证) 提交于 2019-12-03 01:14:02

问题:

I have been learning Objective C lately, and I decided to try connections.

Everything was great with NSURLConnection, until I discovered it was outdated, and tried to work with NSURLSession.

I am trying a very simple example, but can't seem to get my app to run the code inside the completion block.

Here is the code used:

NSURL * url = [NSURL URLWithString:@"http://api.openweathermap.org/data/2.5/weather?q=London,uk"];  NSLog(@"2"); NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration]; NSLog(@"3");  NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject                                                              delegate: nil                                                         delegateQueue: [NSOperationQueue mainQueue]];  NSLog(@"4"); NSURLSessionDataTask * dataTask = [defaultSession dataTaskWithURL:url                                                 completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {                                                     dispatch_sync(dispatch_get_main_queue(), ^{                                                         NSLog(@"11");                                                         if(error == nil)                                                         {                                                             NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];                                                             NSLog(@"Data = %@",text);                                                         }                                                         NSLog(@"22");                                                     });                                                  }];  NSLog(@"5"); [dataTask resume]; NSLog(@"6"); 

I get all the numbers printed from the main execution, but the completionHandler is never executed. I also tried this using a delegate, with no success.

Thanks in advance.

EDIT As suggested, I have changed my function to the following:

-(void) doGET{     NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration     defaultSessionConfiguration];     NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject];     NSURLSessionDataTask * dataTask = [defaultSession dataTaskWithURL:[self url]                                                     completionHandler:^(NSData *data,    NSURLResponse *response, NSError *error) {                                                             NSLog(@"11");                                                             if(error == nil)                                                             {                                                                 NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];                                                                 NSLog(@"Data = %@",text);                                                             }                                                             NSLog(@"22");                                                      }];     [dataTask resume];  } 

My completion manager is still not getting run. I also tried with the sharedSession instead of passing a configuration but no luck either.

Thanks for the help

回答1:

If you're going to use the completion block rendition of the data task, rather than specifying a delegate of nil, like this:

NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject                                                              delegate: nil                                                         delegateQueue: [NSOperationQueue mainQueue]]; 

You should instead instantiate your session using the method that does not take a delegate at all:

NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject]; 

Or, alternatively, given that you're not customizing your configuration at all, you can skip the instantiation of the NSURLSessionConfiguration altogether and use the shared NSURLSession:

NSURLSession *defaultSession = [NSURLSession sharedSession]; 

But, bottom line, you should not use the sessionWithConfiguration:delegate:queue: rendition unless you're going to implement the delegates, in which case you wouldn't use the rendition of the NSURLSessionDataTask method with the completionHandler parameter.

Also, make sure your device/simulator is running iOS 7.0 or greater.



回答2:

Check the location of your code.

Although it is not stated in OP where the code was located, I found, after much looking and many iterations, that putting sample code in -viewDidLoad never executed the completion handler. Moving the code into

- (void)viewWillAppear:(BOOL)animated { } 

solved the never completing task issue. (I still don't understand why though.)



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!