0

根据 的文档NSURLSessionConfiguration::protocolClasses,无法保证将使用我的自定义 url 协议。我如何确保在我将其设置为protocolClasses属性时使用它?

在处理请求之前,NSURLSession 对象首先搜索默认协议,然后检查您的自定义协议,直到找到能够处理指定请求的协议。它使用canInitWithRequest: 类方法返回YES 的协议,表明该类能够处理指定的请求。

我无法使用单个 URL 协议设置数组,因为它具有canInitWithRequest:方法逻辑并且可能无法处理所有请求。

NSArray *currentProtocolClasses = sessionConfiguration.protocolClasses ?: @[];
NSMutableArray *protocolClasses = [NSMutableArray arrayWithArray:currentProtocolClasses];
[protocolClasses insertObject:[CustomURLProtocol class] atIndex:0];
sessionConfiguration.protocolClasses = protocolClasses;
4

1 回答 1

1

如果文档这么说,那是一个错误。请提交一份。逻辑实际上比那里描述的要简单得多。基本上操作系统所做的是:

NSURLProtocol *protocol = nil;
for (Class protocolClass in sessionConfiguration.protocolClasses) {
    if ([protocolClass canInitWithRequest:request]) {
         protocol = [[protocolClass alloc] init];
    }
}
if (!protocol) {
    fail
}

因此,只要您的协议首先列出,它们就会获得优先权。(对于 NSURLConnection,文档的那一点也是错误的;总是先询问您注册的协议,然后再询问任何内置协议。)

如果您不需要处理标准协议,那么您这样做就足够了:

sessionConfiguration.protocolClasses = @[[CustomURLProtocol class]];

您不能强制使用 URL 协议。canInitWithRequest:当且仅当其类方法为请求返回 YES时,才会使用该协议。如果您想让不同的协议处理请求(例如,如果您想定义一个真正使用普通 https 请求的自定义 URL 方案),那么您通常会通过编写一个协议来重写 URL 并重新发出请求一个没有安装协议处理程序类的新会话。

或者,您可以在安装了处理程序的会话中重新发出请求,只要您以某种方式修改请求,以便您的协议处理程序知道在canInitWithRequest:第二次看到请求时从其方法返回 NO。(否则,您将获得无限递归。)

于 2017-05-23T07:28:30.193 回答