NSURLProtocol无法监听AFNetworking3.0请求的解决方案

最近在做Safencrypt安全项目,其实就是对网络请求的数据进行报文级别的加密。为了简化SDK的使用,决定使用NSURLProtocol来自动监听HTTP请求并加密解密。
通过[NSURLProtocol registerClass: [NetworkInject class]];注入了自定义的NSURLProtocol类,在测试直接通过[NSURLSession sharedSession]进行的请求是没问题的,可以拦截到;但是为了更贴近实际,在Demo中使用AFN3.0进行了网络请求,发现并没有拦截成功。经过一番研究发现AFN中是通过

sessionWithConfiguration:delegate:delegateQueue: 

这个方法得到的session,这样得到的session我们监听不到是因为NSURLSessionConfiguration。我们进到NSURLSessionConfiguration里面看一下,他有一个属性@property (nullable, copy) NSArray *protocolClasses;这是一个NSURLProtocol数组,我们监控网络是通过注册NSURLProtocol来进行网络监控的,但是通过 sessionWithConfiguration:delegate:delegateQueue:得到的session,他的configuration中已经有一个NSURLProtocol,所以他不会使用我们的NSURLProtocol。
找到了问题我们开始解决,我们将NSURLSessionConfiguration的属性protocolClasses的get函数替换掉,换成我们自己的函数,返回我们自己的protocol,这样,我们就能够监控到通过 sessionWithConfiguration:delegate:delegateQueue: 得到的session的网络请求,方法如下,在正常我们注册NSURLProtocol的类里面添加如下两个方法,然后调用+ (void)injectNSURLSessionConfiguration这个方法即可。

+ (void)injectNSURLSessionConfiguration{
    Class cls = NSClassFromString(@"__NSCFURLSessionConfiguration") ?: NSClassFromString(@"NSURLSessionConfiguration");
    Method originalMethod = class_getInstanceMethod(cls, @selector(protocolClasses));
    Method stubMethod = class_getInstanceMethod([self class], @selector(protocolClasses));
    if (!originalMethod || !stubMethod) {
        [NSException raise:NSInternalInconsistencyException format:@"Couldn't load NEURLSessionConfiguration."];
    }
    method_exchangeImplementations(originalMethod, stubMethod);
}

- (NSArray *)protocolClasses {
    return @[[NetworkInject class]];
}
NSURLProtocol无法监听AFNetworking3.0请求的解决方案_第1张图片
最后实现的效果图截图

参考文章:https://www.aliyun.com/jiaocheng/359256.html,感谢原作者提供的思路

你可能感兴趣的:(NSURLProtocol无法监听AFNetworking3.0请求的解决方案)