【问题标题】:iOS - Use AFNetworking with custom NSURLProtocol classiOS - 将 AFNetworking 与自定义 NSURLProtocol 类一起使用
【发布时间】:2015-01-26 10:36:28
【问题描述】:

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

本质上,我正在尝试发送HTTP 请求,但不是URL 以“http://”开头,而是需要以“bla://”开头

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

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

除了注册protocolclass之外,我还尝试通过在didFinishLaunchingWithOptions方法中调用来将类添加到AFHTTPSessionManagerprotocolClasses

[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 Schemes 字段中添加了 url 方案

仍然没有运气... 我想要做的甚至可能吗?如果是这样,我会错过什么? 谢谢

【问题讨论】:

  • NSURLProtocol 类中的方法是否被调用?
  • 是的,协议方法似乎工作正常。此外,当我在请求 url 的开头加上“http://”时,服务器会响应(当然响应错误,因为它是错误的协议)。所以请求肯定会被发送。
  • 我刚刚测试了 ryanwa 的建议,它确实有效。

标签: ios objective-c http afnetworking nsurlprotocol


【解决方案1】:

所以,对于其他寻找有关此信息的人:

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

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

【讨论】:

  • 正确答案:将行 [protocolsArray addObject:[MyURLProtocol class]]; 更改为 [protocolsArray insertObject:[MyURLProtocol class] atIndex:0]; 应该可以工作。
【解决方案2】:

所以,首先@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 子类。这在 iPad Mini 4 上的 iOS 9.1 上对我有用。

来自NSURLSession 上的文档:

@property(readonly, copy) NSURLSessionConfiguration *configuration

说明

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 谢谢!很高兴知道。我已将 AFHTTPSessionManager 实例移动到我的应用程序中的单例实用程序类,但不幸的是,这并没有解决我的问题。顺便说一句,当我输入服务器地址时,示例项目给了我相同的结果。我感觉协议本身的实现有问题……
    猜你喜欢
    • 1970-01-01
    • 2016-01-13
    • 1970-01-01
    • 2023-03-22
    • 2014-04-08
    • 2011-09-22
    • 1970-01-01
    • 2017-08-31
    • 2012-04-01
    相关资源
    最近更新 更多