需求的轮子一直在滚动。你上车了没?曾有没发现 Charles 抓取其它 APP 时候,有些数据是无法获取到的?会想到它们是怎么做到的吗?
NSURLProtocol 也是苹果众多黑魔法中的一种,使用它可以轻松地重定义整个URL Loading System。
NSURLProtocol 是苹果为我们提供的 URL Loading System 一部分,先了解下它在整体中的位置。
从图中我们可以知道,NSURLProtocol 可拦截的网络请求包括NSURLSession,NSURLConnection 的以及 UIWebView 中。而基于 CFNetwork 的网络请求,以及在WKWebView 中,只能拦截到最初始的请求,内嵌的资源下载拦截不到。不过本文 Tips 中提供了有效的方法。
Mattt 撰写的 NSURLProtocol 文章中,有张图更清晰的描述了 URL Loading System,下面的 URL 加载系统的图片 版本有点久远,还没有把 NSURLSession 放进来。
那具体些,NSURLProtocol 能处理些什么问题呢?当你注册自定义 NSURLProtocol 后,就有机会对所有的请求进行统一的处理,基于这一点它可以让你:
1.自定义网络请求和响应结果
2.提供自定义的全局缓存支持|实现网络缓存。
3.重定向网络请求,实现代理等功能。
4.对 HTTP 返回内容进行Mocking 和Stub (方便前期测试) 。
5.全局设置网络请求。
如何使用
要使用 NSURLProtocol 时你是不能直接实例化 NSURLProtocol 的因为这是一个抽象类只提供基本的功能和属性,你只能子类化 NSURLProtocol 。
创建分类继承。
当NSURLConnection准备发起请求时,它会遍历所有已注册的NSURLProtocol,询问它们能否处理当前请求。所以你需要尽早注册这个Protocol。
Tip:
1、目前 WKWebView 无法被 NSURLProtocol 直接拦截,还得用本身的代理。若要支持,那可以参考 Wasteland 的深度好文 - 让 WKWebView 支持 NSURLProtocol。
参考链接:
官方文档:https://developer.apple.com/documentation/foundation/nsurlprotocol