An NSURLProtocol
object handles the loading of protocol-specific URL data. The NSURLProtocol
class itself is an abstract class that provides the infrastructure for processing URLs with a specific URL scheme. You create subclasses for any custom protocols or URL schemes that your app supports.
大概意思是NSURLProtocol是用來處理URL數(shù)據(jù)加載的類隔心。它本身是一個抽象類椅贱,并為處理網(wǎng)絡(luò)請求提供基礎(chǔ)一個殼怀跛,你可以子類化它萍丐,重新定義新的或已存在的URL的行為拣宰。
可能還是不明白有什么鬼用党涕,接下來我們來看一張圖,你就能很容易明白他在整個系統(tǒng)中地位了巡社。這張圖可能有點老了膛堤,沒有把NSURLSession 放進來.
雖然URL加載系統(tǒng)包含很多東西,一層又一層的裝飾設(shè)計晌该,造就龐大的URL Loading System肥荔。NSURLProtocol或許是URL加載系統(tǒng)中最功能強大但同時也是最晦澀的部分了。用了它朝群,你不必改動應(yīng)用在網(wǎng)絡(luò)調(diào)用上的其他部分燕耿,就可以改變URL加載行為的全部細節(jié)。 對現(xiàn)有的AFNetworking 姜胖、SDWebImage 等你都可以重新修改其中網(wǎng)絡(luò)請求和響應(yīng)缸棵。
- 比如攔截圖片加載請求,轉(zhuǎn)而從本地文件加載谭期。之前半糖的文章HTML發(fā)布文章預覽功能就是通過他實現(xiàn)的
- 對請求進行HTTPDNS解析堵第,動態(tài)設(shè)置Host,解決不同網(wǎng)絡(luò)下客戶端不能訪問的情況
- 對請求和返回的數(shù)據(jù)進行敏感信息過濾
- 對請求進行驗證簽名
- 自定義網(wǎng)絡(luò)請求和返回結(jié)果
- 實現(xiàn)網(wǎng)絡(luò)緩存
1隧出、 創(chuàng)建NSURLProtocol的子類踏志,重寫以下方法
+ canInitWithRequest: 抽象方法,子類給出是否能相應(yīng)該請求胀瞪。如果響應(yīng)YES针余,說明自己的CustomURLProtocol實現(xiàn)該請求饲鄙。
+ canonicalRequestForRequest:抽象方法,重寫該方法圆雁,可以對請求進行修改忍级,例如添加新的頭部信息,修改伪朽,修改url等轴咱,返回修改后的請求。
+ requestIsCacheEquivalent:toRequest:Returns whether two requests are equivalent for cache purposes.
- startLoading開始下載烈涮,需要在該方法中發(fā)起一個請求朴肺,對于NSURLConnection來說,就是創(chuàng)建一個NSURLConnection坚洽,對于NSURLSession戈稿,就是發(fā)起一個NSURLSessionTask 。一般下載前需要設(shè)置該請求正在進行下載讶舰,防止多次下載的情況發(fā)生
<pre class=”brush: java; gutter: true;”>
[NSURLProtocol setProperty:@(YES) forKey:protocolKey inRequest:request];
</pre>
- - stopLoading 停止相應(yīng)請求鞍盗,清空請求Connection 或 Task
2、定義自己的網(wǎng)絡(luò)請求
實現(xiàn)startLoading中代理協(xié)議方法跳昼。 對NSURLConnection來說橡疼,要實現(xiàn)NSURLConnectionDataDelegate代理方法,對于NSURLSession來說庐舟,需要實現(xiàn)NSURLSessionTaskDelegate代理方法欣除。在這些協(xié)議方法中需要通過NSURLProtocolClient 通知URL Loading System
/*-URLProtocol:cachedResponseIsValid:
-URLProtocol:didCancelAuthenticationChallenge:
-URLProtocol:didFailWithError:
-URLProtocol:didLoadData:
-URLProtocol:didReceiveAuthenticationChallenge:
-URLProtocol:didReceiveResponse:cacheStoragePolicy:
-URLProtocol:wasRedirectedToRequest:redirectResponse:
-URLProtocolDidFinishLoading:
*/
3、合適的位置注冊自定義的NSURLProtocol子類
調(diào)用[NSURLProtocol registerClass:[CustomURLProtocol class]]
進行注冊挪略,調(diào)用[NSURLProtocol unregisterClass:[CustomURLProtocol class]]注銷
結(jié)束
- 自定義HttpDNSImageURLProtocol 實現(xiàn)了對SDWebImage 框架中圖片加載連接的攔截历帚,通過攔截請求域名動態(tài)解析出對應(yīng)的訪問IP,重設(shè)請求Host杠娱,優(yōu)化圖片加載挽牢。
-源碼下載地址
參考
- http://nshipster.cn/nsurlprotocol/
- https://developer.apple.com/reference/foundation/nsurlprotocol?language=objc
- http://www.cnblogs.com/fengmin/p/5484413.html
- http://stackoverflow.com/questions/5572258/ios-webview-remote-html-with-local-image-files
- http://www.infinite-loop.dk/blog/2011/09/using-nsurlprotocol-for-injecting-test-data/
- http://www.reibang.com/p/7c89b8c5482a
- https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html#//apple_ref/doc/uid/10000165i