NSURLSessionDataTask 完成处理程序未在命令行项目中执行

NSURLSessionDataTask completion handler not executing in command line project

我查看了多个关于此问题的堆栈溢出帖子,并尝试实施这些修复但无济于事。此问题的前两个答案均无效 NSURLSessionDataTask not executing the completion handler block

这是我的非常简单的代码

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
@autoreleasepool {
    NSURLSession* session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"https://itunes.apple.com/search?term=apple&media=software"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        NSLog(@"%@", json);
    }];

    [dataTask resume];
}
return 0;
}

我从来没有得到任何控制台输出。

我试过以不同的方式实例化会话,比如

 [NSURLSession sharedSession]

没用,

以及尝试在不同的线程中执行完成块中的代码

 dispatch_sync(dispatch_get_main_queue(), ^{
   // Completion code goes here
 });

这也没有用。

我也尝试过不同的 URL。我不知道为什么它不起作用。

在main函数中添加这段代码。

 [[NSRunLoop currentRunLoop] run];

此代码将使运行循环保持不变运行,以便可以完全执行请求。

每个progress都有一个线程,默认是主线程。一个程序一般以 return 0; 结束,也就是说,你的命令行程序将在最后一行 return 0; 之后退出,不管那里有多少线程存活。

如果想得到请求响应,应该让主线程等待,直到后台请求线程完成任务。看看dispatch_semaphore_signal,对你有帮助。

通用 iOS/macOS UI 应用程序怎么样?因为它们内部有一个名为event loop的无限循环来接收用户交互,所以不会立即调用主函数中的return 0;

默认情况下,命令行界面没有运行循环,因此异步任务无法运行。

您必须明确地启动和停止运行循环

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        CFRunLoopRef runloop = CFRunLoopGetCurrent();
        NSURLSession* session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
        NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"https://itunes.apple.com/search?term=apple&media=software"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
            NSLog(@"%@", json);
            CFRunLoopStop(runloop);
        }];

        [dataTask resume];
        CFRunLoopRun();
    }
    return 0;
}

您应该处理 dataTask 错误以退出值 != 0