iOS - 将 AFNetworking 与自定义 NSURLProtocol 结合使用 class

iOS - Use AFNetworking with custom NSURLProtocol class

我有一个自定义 NSURLProtocol class 是在 this tutorial 的帮助下实现的。除了名称、数据模型等之外,我的实现与教程中的几乎相同...

本质上,我试图发送一个 HTTP 请求,但不是 URL 开头:"http://",它需要开头,比如:"bla://"

现在,我正在尝试注册 protocol class 并通过 AFNetworking framework 使用它,但我遇到了一些麻烦。

canInitWithRequest: 方法在某个时候开始返回 NO,此时请求失败,我不断收到 "unsupported URL" 错误。

除了注册 protocol class,我还尝试通过在didFinishLaunchingWithOptions方法:

[NSURLProtocol registerClass:[MyURLProtocol class]];
NSMutableArray *protocolsArray = [NSMutableArray arrayWithArray:[AFHTTPSessionManager manager].session.configuration.protocolClasses];
[protocolsArray addObject:[MyURLProtocol class]];
[AFHTTPSessionManager manager].session.configuration.protocolClasses = [protocolsArray copy];

而且我还在应用的 info.plist

的 URL 方案字段中添加了 url 方案

仍然没有运气...... 我正在尝试做的事情有可能吗?如果是这样,我会错过什么? 谢谢

[AFHTTPSessionManager manager] 不是 return 单例对象,而是 return 一个全新的实例。因此,如果您只是在 didFinishLaunchingWithOptions 中为 AFHTTPSessionManager 的一个实例设置 protocolClasses,但在其他地方使用 [AFHTTPSessionManager manager] 创建的另一个实例,则新管理器没有您的自定义协议 class 已注册。这可能会导致问题。

所以,对于其他正在寻找这方面信息的人:

除了 AFURLSessionManager 不使用标准 NSURLProtocol 注册之外,它还处理数组先进先出,而不是像后进先出NSURLProtocol

意思是,如果你想覆盖 AFURLSessionManager 的行为(比如出于测试目的),你不能只将你的 NSURLProtocol 子类添加到 session.configuration.protocolClasses,你必须而是将其添加到数组的开头(或者至少在您 overwriting/modifying 的行为之前)。

因此,首先@dopcn 是正确的,您需要保留 AFHTTPSessionManager.

的实例

@ryanwa 部分正确,您需要在数组的开头插入新协议,但它仍然不起作用,因为在 NSURLSession 完成后无法更改配置。正确的解决方案是使用 initWithSessionConfiguration:

NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSMutableArray * protocolsArray = [sessionConfiguration.protocolClasses mutableCopy];
[protocolsArray insertObject:[MyURLProtocol class] atIndex:0];
sessionConfiguration.protocolClasses = protocolsArray;
AFHTTPSessionManager * myManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:sessionConfiguration]; //retain this somewhere!

据我所知,您不需要向 registerClass 注册您的 NSURLProtocol 子类。这对 iOS 9.1 在 iPad Mini 4 上对我有用。

来自 NSURLSession 上的文档:

@property(readonly, copy) NSURLSessionConfiguration *configuration

Description

A copy of the configuration object for this session. (read-only) Changing mutable values within the configuration object has no effect on the current session, but you can create a new session with the modified configuration object.