注册多个 NSURLProtocol 子类 & 如何拦截 WKWebView
注册多个 NSURLProtocol 子类
当有多个自定义 NSURLProtocol 子类注册到系统中的话,会按照他们注册的反向顺序依次调用 URL 加载流程,也就是最后注册的 NSURLProtocol 会被优先判断。
对于通过配置 NSURLSessionConfiguration 对象的 protocolClasses
属性来注册的情况,protocolClasses
数组中只有第一个 NSURLProtocol 会起作用,后续的 NSURLProtocol 就无法拦截到了。
所以 OHHTTPStubs 在注册 NSURLProtocol 子类的时候是这样处理的:
+ (void)setEnabled:(BOOL)enable forSessionConfiguration:(NSURLSessionConfiguration*)sessionConfig
{
// Runtime check to make sure the API is available on this version
if ([sessionConfig respondsToSelector:@selector(protocolClasses)]
&& [sessionConfig respondsToSelector:@selector(setProtocolClasses:)])
{
NSMutableArray * urlProtocolClasses = [NSMutableArray arrayWithArray:sessionConfig.protocolClasses];
Class protoCls = HTTPStubsProtocol.class;
if (enable && ![urlProtocolClasses containsObject:protoCls])
{
// 将自己的 NSURLProtocol 插入到 protocolClasses 的第一个,进行拦截
[urlProtocolClasses insertObject:protoCls atIndex:0];
}
else if (!enable && [urlProtocolClasses containsObject:protoCls])
{
// 拦截完成后移除
[urlProtocolClasses removeObject:protoCls];
}
sessionConfig.protocolClasses = urlProtocolClasses;
}
else
{
NSLog(@"[OHHTTPStubs] %@ is only available when running on iOS7+/OSX9+. "
@"Use conditions like 'if ([NSURLSessionConfiguration class])' to only call "
@"this method if the user is running iOS7+/OSX9+.", NSStringFromSelector(_cmd));
}
}
复制代码
如何拦截 WKWebView
虽然 NSURLProtocol 无法直接拦截 WKWebView,但其实还是有解决方案的。就是使用 WKBrowsingContextController
和 registerSchemeForCustomProtocol
。
// 注册 scheme
Class cls = NSClassFromString(@"WKBrowsingContextController");
SEL sel = NSSelectorFromString(@"registerSchemeForCustomProtocol:");
if ([cls respondsToSelector:sel]) {
// 通过 http 和 https 的请求,同理可通过其他的 Scheme 但是要满足 URL Loading System
[cls performSelector:sel withObject:@"http"];
[cls performSelector:sel withObject:@"https"];
}
复制代码
但由于这涉及到了私有方法,直接引用无法过苹果的机审,所以使用的时候需要对字符串做下处理,比如对方法名进行算法加密处理等,实测也是可以通过审核的。
总之,NSURLProtocol 非常强大,无论是优化 App 的性能,还是拓展功能,都具有很强的可塑空间,但在使用的同时,又要多关注它带来的问题。尽管它在很多框架或者知名项目中都已经得以应用,其奥义依然值得开发者们去深入研究。
作者:FiTeen
链接:https://juejin.cn/post/6844904079458566152
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
我思故我在