http://blog.csdn.net/horisea/article/details/53815596
一:前言:項目中整個一tab頁因為需求變成了加載webView,沒網(wǎng)情況下會一片白邪狞。祷蝌。很多APP無網(wǎng)顯示的是一張圖片,筆者強迫癥帆卓,堅決做到最好的用戶體驗巨朦,于是緩存了整個webview;
1. 想通過加載HTMLSting字符串緩存webView是不可行剑令, [self.webView loadHTMLString:HTMLSting baseURL:nil];想走這條路的哥們這里說下糊啡,肯定是不行的。吁津。簡單說下原因:正常的一個h5網(wǎng)頁棚蓄,包含.css樣式,.JS等事件,這些都是外部引用的梭依。稍算。所以你緩存不下來。睛挚。邪蛔。但是如果樣式啥的都是內(nèi)聯(lián)(類似iOS MVC都在控制器里),那么用這個方法是可行的扎狱。侧到。。
2.WKWebView能用這個緩存嗎淤击? ?當(dāng)然不可以匠抗,它不走NSURLProtocol機制,所以不會對URL進行攔截污抬。
3.通過NSURLProtocol是最快捷的方法汞贸,下面開始介紹。
插曲:如果你不喜歡看啰嗦的文字印机,直接上github地址了矢腻,https://github.com/horisea/NSURLProtocol-webView,歡迎star射赛,有網(wǎng)情況下運行一次多柑,斷網(wǎng)再運行,網(wǎng)頁依舊出現(xiàn)楣责,OK
二:NSURLProtocol是什么竣灌?3句話,簡單粗暴秆麸。 (想了解透徹的話初嘹,自己搜去吧)
個人理解:1.當(dāng)你自定義了繼承自NSURLProtocol的子類后,
2.在注冊完畢后
3.所有的網(wǎng)絡(luò)請求都會走你自定義的protocol類沮趣,那你想干嘛就可以干嘛了(離線緩存主要是緩存所有的response屯烦,data數(shù)據(jù)),比如(重定向兔毒,離線緩存)
三:就上面3點漫贞,一點點細說
1.繼承自NSURLProtocol,項目中有完整的育叁,拷貝出來用就行了
2.注冊:ViewDidLoad方法中寫就行迅脐,(想攔截哪一條URL,想緩存哪一個豪嗽,在發(fā)起請求前注冊就行了)
[NSURLProtocol registerClass:[SCYCacheURLProtocol class]];
3.在自定義的NSURLProtocol中谴蔑,要做的事情就多了 豌骏。。下面介紹下一些方法的調(diào)用順序等需要處理的隐锭∏远悖看第四大模塊吧。
四:1.+ (BOOL)canInitWithRequest:(NSURLRequest *)request钦睡;
作用:(1).處理返回YES蒂窒,不處理返回NO
(2).打標(biāo)簽,已經(jīng)處理過的不在處理
這篇文章有具體說明:http://www.reibang.com/p/7c89b8c5482a
2.+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request荞怒;
作用:做緩存的話洒琢,沒什么用;
3.- (void)startLoading
作用:開始加載時自動調(diào)用 褐桌,作用大了去了衰抑,該方法里判斷,有緩存時加載緩存荧嵌,沒緩存再去請求呛踊,demo里該方法有具體詳細邏輯
#pragma mark - NSURLConnectionDelegate
1.- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
}
作用.緩存response
2.- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.client URLProtocol:self didLoadData:data];
}
作用:拼接data,也是緩存用
3.- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
[self.client URLProtocolDidFinishLoading:self];
}
作用:一條請求加載完畢后調(diào)用啦撮,谭网,還是緩存的作用。赃春。
4.- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[self.client URLProtocol:self didFailWithError:error];
}
五:溫馨提示:非常重要蜻底,你可能迷惑的坑
0. 文中的所有key是當(dāng)前加載的url加md5加密的字符串;
1. 運行項目聘鳞,你會發(fā)現(xiàn),我只是加載了一個url要拂,為毛緩存達到了64個
關(guān)閉網(wǎng)絡(luò):第二次運行抠璃,會給出所有的緩存key,脱惰,這也回答了筆者一開始說的.css樣式文件搏嗡,以及.js文件都被緩存下來了。拉一。所以這里不回出現(xiàn)像LoadHTMLString緩存只出現(xiàn)光禿禿的文字采盒,沒了樣式的webView
http://csdnimg.cn/public/common/libs/bootstrap/css/bootstrap.css
http://csdnimg.cn/public/static/css/avatar.css
http://m.blog.csdn.NET/static/css/common.css
http://m.blog.csdn.Net/static/js/libs/html5shiv.min.js
http://m.blog.csdn.net/static/js/apps/blog_mobile.js
2.文中的緩存策略,筆者用的是YYCache 蔚润。磅氨。緩存對象是個單例,里面放了64條緩存數(shù)據(jù)嫡纠,烦租,當(dāng)控制器傳入的url和緩存的key不一樣時延赌,把單例對象的64個緩存,都倒掉叉橱,然后在加入新的挫以。。(既然要緩存窃祝,那肯定是會有新的緩存掐松,別忘了刪除之前的緩存,還有之前的緩存不是一條粪小,而是一大坨大磺,發(fā)現(xiàn)這一點,我走了很大的坑)
3. demo中給的鏈接緩存了是64個糕再,那么就是自定義的NSURLProtocol被調(diào)用了64次量没;所以一些有關(guān)于記錄的東西,最好保存在NSUserDefaults中突想;
六:https://github.com/horisea/NSURLProtocol-webView在上一次github地址吧殴蹄。。如果幫助了你猾担,就給個star吧袭灯,另外這一塊確實很饒人,建議斷點跟蹤绑嘹,一上午估計就能明白點什么稽荧。。
如果文中有不對的地方工腋,或者您有問題解決不了姨丈,可以扣扣聯(lián)系 ?樓 主,http://blog.csdn.net/horisea/article/details/51872619博客最下方有樓主聯(lián)系方式擅腰。蟋恬。。轉(zhuǎn)載注明出處咯