iOS-将AFNetworking与自定义NSURLProtocol类一起使用

iOS-将AFNetworking与自定义NSURLProtocol类一起使用,ios,objective-c,http,afnetworking,nsurlprotocol,Ios,Objective C,Http,Afnetworking,Nsurlprotocol,我有一个自定义的NSURLProtocol类,它是在的帮助下实现的。除了名称、数据模型等之外,我的实现与教程中的几乎相同 本质上,我试图发送一个HTTP请求,但它需要以“bla://”开头,而不是以“HTTP://”开头的URL 现在,我正在尝试注册协议类,并通过AFNetworking框架使用它,但遇到了一些问题 canInitWithRequest:方法在某个点开始返回NO,此时请求失败,我不断收到一个“不支持的URL”错误 除了注册协议类,我还尝试通过调用didfishlaunchingw

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

本质上,我试图发送一个
HTTP
请求,但它需要以“bla://”开头,而不是以“HTTP://”开头的
URL

现在,我正在尝试注册
协议
,并通过
AFNetworking
框架
使用它,但遇到了一些问题

canInitWithRequest:
方法在某个点开始返回NO,此时请求失败,我不断收到一个“不支持的URL”错误

除了注册
协议
,我还尝试通过调用
didfishlaunchingwithoptions
方法将该类添加到
AFHTTPSessionManager
协议类

[NSURLProtocol registerClass:[MyURLProtocol class]];
NSMutableArray *protocolsArray = [NSMutableArray arrayWithArray:[AFHTTPSessionManager manager].session.configuration.protocolClasses];
[protocolsArray addObject:[MyURLProtocol class]];
[AFHTTPSessionManager manager].session.configuration.protocolClasses = [protocolsArray copy];
我还将url方案添加到应用程序info.plist的url方案字段中

还是没有运气。。。 我想做的事可能吗?如果是这样,我会错过什么?
谢谢

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

因此,对于其他正在查找此信息的用户:

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


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

因此,首先@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!
据我所知,您不需要将您的
NSURLProtocol
子类注册到
registerClass
。这对我在iPadmini4上的iOS9.1上很有效

NSURLSession
上的文档:

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!
@property(只读,复制)NSURLSessionConfiguration*配置

说明

此会话的配置对象的副本。 (只读)更改配置对象内的可变值 对当前会话没有影响,但可以创建新会话 使用修改后的配置对象


NSURLProtocol类中的方法是否被调用?是的,协议方法似乎工作正常。此外,当我将“http://”放在请求url的开头时,服务器响应(当然是错误的响应,因为它是错误的协议)。所以请求肯定是被发送的。我刚刚测试了ryanwa的建议,它很有效。谢谢!知道这一点很好。我已经在我的应用程序中将AFHTTPSessionManager实例移动到了singleton实用程序类中,但不幸的是,这并没有解决我的问题。顺便说一句,当我输入我的示例时,该示例项目给了我相同的结果服务器地址。我感觉协议本身的实现有问题……正确答案:将行
[protocolsArray addObject:[MyURLProtocol class]];
更改为
[protocolsArray insertObject:[MyURLProtocol class]atIndex:0];
正常工作。