【问题标题】:NSURLSessionDataTask dataTaskWithURL completion handler not getting calledNSURLSessionDataTask dataTaskWithURL 完成处理程序没有被调用
【发布时间】:2014-05-01 19:28:41
【问题描述】:

我最近一直在学习 Objective C,我决定尝试连接。

NSURLConnection 一切都很好,直到我发现它已经过时,并尝试使用 NSURLSession。

我正在尝试一个非常简单的示例,但似乎无法让我的应用程序运行完成块内的代码。

这里是使用的代码:

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");

我从主执行中打印了所有数字,但从不执行完成处理程序。我也尝试过使用委托,但没有成功。

提前致谢。

编辑 按照建议,我已将我的功能更改为以下内容:

-(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];

}

我的完成管理器仍然没有运行。我也尝试使用 sharedSession 而不是传递配置,但也没有运气。

感谢您的帮助

【问题讨论】:

  • 你有没有让这个代码工作?我的代码几乎相同(我认为我们访问了相同的网站),我也无法调用完成代码块。但是,我正在使用 iOS 模拟器 7.1 将我的代码作为单元测试运行,我想知道这是否有任何影响。我还修改了NSURLSession,但这些都没有帮助。我注意到您将问题标记为已回答,但仍不清楚答案是什么?

标签: ios objective-c nsurlsession


【解决方案1】:

检查代码的位置。

虽然 OP 中没有说明代码的位置,但我发现,经过多次查找和多次迭代,将示例代码放入 -viewDidLoad 从未执行过完成处理程序。将代码移入

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

解决了无法完成任务问题。 (我还是不明白为什么。)

【讨论】:

    【解决方案2】:

    如果您要使用数据任务的完成块再现,而不是指定 delegatenil,如下所示:

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

    您应该使用完全不使用delegate 的方法来实例化您的会话:

    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject];
    

    或者,如果您根本没有自定义配置,您可以完全跳过 NSURLSessionConfiguration 的实例化并使用共享的 NSURLSession

    NSURLSession *defaultSession = [NSURLSession sharedSession];
    

    但是,最重要的是,除非您要实现委托,否则不应使用 sessionWithConfiguration:delegate:queue: 演绎版,在这种情况下,您不会使用带有 completionHandler 参数的 NSURLSessionDataTask 方法的演绎版。

    另外,请确保您的设备/模拟器运行的是 iOS 7.0 或更高版本。

    【讨论】:

    • 我尝试使用各种不同的方法来做到这一点:使用自定义委托、您提供的建议以及我在上面发布的建议。问题是我没有从完成处理程序(或我使用它时的委托)中获取 NSLog 操作。我的代码有点混合了我所采用的所有方法,所以它可能不是最好的,但我无法获取委托或完成处理程序来打印任何内容。我不确定为什么,因为我读过的所有内容都表明它应该这样做。你知道是否还有其他原因它不会“执行”完成处理程序?在此先感谢
    • 我已根据您的建议编辑了帖子,但即使使用新功能,completionHandler 也没有反应
    • @user3214816 你是在 iOS 7 上运行这个吗?如果您在 iOS 6.1 上运行,则不会出现异常(我对此感到惊讶),而是 defaultSession 将是 nildataTask 也是如此。除了那种情况,我不知道为什么它不起作用,因为您的代码在我的 iOS 7.x 设备和 iOS 7.x 模拟器上运行良好。我建议记录defaultSessiondataTask,看看你是否得到了有效的对象。
    • 我在命令行应用程序上运行它,因为我只是在执行漏洞应用程序之前对其进行测试。谢谢,使用真正的应用程序可以正常工作!
    • @Rob 在互联网上搜索时,有许多发布数据的示例遵循 OP 提供的完全相同的代码(例如,使用数据任务的完成块再现)。那么,如果我们遵循您的建议(没有委托,因此没有完成块),我们应该如何处理 HTTP 响应?除非我们只是简单地发布并且不关心响应,否则我看不出这个建议会有什么用(除非有另一种方法可以在 HTTP 响应通过后挂钩回调)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    相关资源
    最近更新 更多