我已经查看了有关此问题的多个堆栈溢出帖子,并试图实现这些修复无济于事。这个问题的前两个答案都没有起作用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
});
也没用。
我也尝试过不同的网址。我不知道为什么它不起作用。
答案 0 :(得分:2)
默认情况下,命令行界面没有runloop,因此异步任务无法正常工作。
你必须明确地启动和停止runloop
#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
答案 1 :(得分:1)
在main函数中添加此代码。
[[NSRunLoop currentRunLoop] run];
此代码将保持runloop仍然运行,以便可以完全执行请求。
答案 2 :(得分:1)
每个进程都有一个线程,默认情况下是主线程。程序一般以return 0;
结束,也就是说,无论在那里有多少线程,你的命令行程序将在最后一行return 0;
之后退出。
如果要获取请求响应,则应让主线程等待,直到后台请求线程完成任务。检查dispatch_semaphore_signal
,它可以帮助您。
通用iOS / macOS UI应用程序如何?因为它们内部有一个名为event loop
的无限循环来接收用户交互,所以主函数中的return 0;
不会立即被调用。