我有一些长期代码使用NSUrlConnection来发出异步请求,还有一个completionHandler块来处理它。我不久前切换到NSUrlSession,对于一些小的额外内容,但主要假设它们在实现中类似。他们都以同样的方式接受了我的completionHandler块,并在完成时调用它。设置略有不同。
最近我发现了一个令人不安的问题,即NSUrlSession在实际发生错误时没有向completionHandler块返回NSError。该用例适用于http 401 auth问题,通常会返回NSError代码-1012。对于NSUrlSession,NSError为nil。
无论我是否使用代表,都是如此。并且也没有返回didFailWithError委托。
为什么NSUrlSession不会返回此错误?
void (^connectionCompletionHandlerBlock)(NSData *data, NSURLResponse *response, NSError *error) = ^(NSData *data, NSURLResponse *response, NSError *error){
if(error){
// handle error
if(error.code == -1012){ // such as http 401 login error
// auth error
}
} else {
// no error
}
}
NSString *url = @"http://blahblah.com";
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
// configure urlRequest with params, etc
NSUrlConnection方式:(错误-1012返回401错误)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:connectionCompletionHandlerBlock];
NSUrlSession方式:( 401错误没有返回错误-1012)
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig];
NSURLSessionDataTask *task = [session dataTaskWithRequest:urlRequest completionHandler:connectionCompletionHandlerBlock];
[task resume];
我期望获得的401错误:
错误域= NSURLErrorDomain代码= -1012“(null)”UserInfo = {NSErrorFailingURLStringKey = https://api/blah,NSUnderlyingError = 0x600004047890 {错误域= kCFErrorDomainCFNetwork代码= -1012“(null)”UserInfo = {_ kCFURLErrorAuthFailedResponseKey = { url = https://api/blah}}},NSErrorFailingURLKey = https://api/blah}
答案 0 :(得分:2)
经过一番研究后发现。根据设计,NSUrlSession不会返回服务器端错误。
来自NSUrlSession Apple documentation
注意:NSURLSession不会通过错误报告服务器错误 参数。您的应用通过错误收到的唯一错误 参数是客户端错误,例如无法解析 主机名或连接到主机。
通过报告服务器端错误 NSHTTPURLResponse对象中的HTTP状态代码。更多 信息,阅读NSHTTPURLResponse的文档和 NSURLResponse课程。