AFNetworking iOS11 - HTTP加载失败-999

5
我有一个在生产中运行良好一段时间的应用程序。然而,自从iOS 11以来,我收到了这个错误:

任务<51E07EF5-6F31-4E58-8818-7712CB3E49A6>.<20> HTTP加载失败(错误代码:-999 [1:89]) 任务<51E07EF5-6F31-4E58-8818-7712CB3E49A6>.<20>以错误代码-999完成

这仅发生在iOS 11上。此外,它并不一致。在同一URL上的五个请求中,有两个会失败。在蜂窝连接上,它发生得不那么频繁,但仍然存在。
我正在使用AFNetworking,并且像我所说的,这从未是问题,直到iOS 11。
有什么想法?
更新以添加更多细节:
我正在使用有效证书的SSL Pinning。我的info.plist文件如下:
<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>url.com</key>
            <dict>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSExceptionRequiresForwardSecrecy</key>
                <false/>
                <key>NSIncludesSubdomains</key>
                <true/>
            </dict>
        </dict>
    </dict>

像这样使用SSL pinning:

    NSString *pathToProdCert = [[NSBundle mainBundle]pathForResource:@"MY_CERT" ofType:@"cer"];

if(pathToProdCert){
       manager.securityPolicy.pinnedCertificates = [NSSet setWithObjects[NSData dataWithContentsOfFile:pathToProdCert], nil];
            manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];
        }

更新: 回应评论:下面是这个管理器的声明:

@property (nonatomic) AFHTTPSessionManager *manager;

经理对象是通过我的 Web 服务类的 init 方法进行初始化的:
-(instancetype)initWithBaseUrl:(NSURL *)url {

    self  = [super init];
    if (self){
        self.manager = [[AFHTTPSessionManager alloc] initWithBaseURL:url];
        self.manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    }

    return self;
}

每个应用程序会话只初始化一次。

更新: 根据要求,这是error中的userInfo

NSErrorFailingURLKey = "https://MY_URL/PARAMS"; NSErrorFailingURLStringKey = "https://MY_URL/PARAMS"; NSLocalizedDescription = cancelled; NSUnderlyingError = "Error Domain=kCFErrorDomainCFNetwork Code=-999 \"(null)\" UserInfo={_kCFStreamErrorCodeKey=89, _kCFStreamErrorDomainKey=1}"; "_kCFStreamErrorCodeKey" = 89; "_kCFStreamErrorDomainKey" = 1;

经过更多测试,我注意到如果我在每个网络调用时重新创建网络类,在其中声明manager,我就不会遇到这个错误。


你在info.plist中设置了NSAppTransportSecurity设置吗? - gotomanners
@gotomanners - 抱歉,我忘了提到。我已经将NSAllowsArbitraryLoads设置为true。 - Robert J. Clegg
@JörnEyrich 将[userInfo]中的信息添加到问题中。至于在Task上设置断点 - 我应该在哪里设置?试图弄清楚库中icancel的设置位置 - 但无法看出是什么导致了取消。 - Robert J. Clegg
你看过这个吗:https://dev59.com/JpHea4cB1Zd3GeqPmTo1?(特别是问题作者的评论。) - Phillip Mills
请参考这个类似的问题:Error Domain=NSURLErrorDomain Code=-999 "cancelled" - Krunal
显示剩余5条评论
3个回答

4

-999ErrorCancelled

初始化的管理器未被拥有,当其超出作用域后会被释放。因此,任何挂起的任务都将被取消。

创建一个带有AFHTTPSessionManager的单例类,并将其用于所有请求。

YourAPIClient.h

#import "AFHTTPSessionManager.h"
@interface YourAPIClient : AFHTTPSessionManager
+(YourAPIClient *) sharedClient;
@end

YourAPIClient.m

#import "YourAPIClient.h"

@implementation YourAPIClient

//Singleton Shared Client
+(YourAPIClient *)sharedClient
{
    static YourAPIClient *_sharedClient = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];

        // Initialize Session Manager
       _sharedClient = [[YourAPIClient alloc] initWithSessionConfiguration:sessionConfiguration];
        // Configure Manager
        [_sharedClient setResponseSerializer:[AFHTTPResponseSerializer serializer]];

    });

    return _sharedClient;
}

我理解这一点,这是我探索过的内容。但我不明白的是,为什么这只是在iOS11+设备上出现问题,而之前的iOS版本却没有出现呢? - Robert J. Clegg

1
我们有一个类似的案例。对于我们的特定情况,客户在企业网络内使用应用程序,该网络向每个请求注入公司证书。如果设备没有公司的自定义CA,则用户将收到此特定错误。

这不是我遇到的问题。正如提到的,我们甚至在蜂窝网络上也遇到了这个问题。这排除了公司证书的问题。感谢您的意见。 - Robert J. Clegg

0

这似乎是 iOS 的一个bug。与HTTP load failed(CFErrorDomainCFNetwork)相关联的错误代码999表示已取消请求(cfurlErrorCancelled)。

你自己已经回答了这个问题。为了让它在 iOS 11 上工作,你应该考虑为每个调用使用不同的管理器,因为似乎一个管理器上的网络请求会互相冲突。

参考资料:

https://github.com/AFNetworking/AFNetworking/issues/3999 https://developer.apple.com/documentation/cfnetwork/cfnetworkerrors/1416998-cfurlerrorcancelled iOS中的NSURLErrorDomain错误代码-999


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接