iOS關於WKWebView緩存總結


  近期公司樓下實體店的網絡及其不穩定,經常有用戶反饋App里的網頁打開特別慢,進度條一直加載不完,體驗很差,於是就有了webview緩存的需求,項目里使用的是WKWebView,而且蘋果早就不提倡使用UIWebView了,這里也不做贅述了。

  • WKWebView 支持的緩存策略枚舉

    * 參見 蘋果官方文檔

    typedef NS_ENUM(NSUInteger, NSURLRequestCachePolicy)
    {
        NSURLRequestUseProtocolCachePolicy = 0, // 默認策略,具體的緩存邏輯和協議的聲明有關,如果協議沒有聲明,不需要每次重新驗證cache。
        NSURLRequestReloadIgnoringLocalCacheData = 1, // 忽略本地緩存,直接從后台請求數據
        NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, //  iOS 13 實現,忽略本地緩存數據、代理和其他中介的緩存,直接從后台請求數據
        NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData        
        NSURLRequestReturnCacheDataElseLoad = 2, // // 優先從本地拿數據,且忽略請求生命時長和過期時間。但是如果沒有本地cache,則請求源數據
        NSURLRequestReturnCacheDataDontLoad = 3,  //只從本地拿數據
        NSURLRequestReloadRevalidatingCacheData = 5, // iOS 13才實現,從原始地址確認緩存數據的合法性后,緩存數據就可以使用,否則從原始地址加載。
    };
  • WKWebView使用緩存方式:

    // 使用默認策略舉例
    NSURLRequest *request =[NSURLRequest requestWithURL:[NSURL URLWithString:self.urlString]
                                                                   cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                               timeoutInterval:20];
    [_webView loadRequest:request];

    我們需要注意一下 NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4 和  NSURLRequestReloadRevalidatingCacheData = 5 在iOS13之前並未實現該協議,所以如果使用該協議一定要注意系統版本判斷。

    官方文檔說明:

  • WKWebView 默認的緩存策略 NSURLRequestUseProtocolCachePolicy = 0 

    • 官方文檔關於HTTP和HTTPS的NSURLRequestUseProtocolCachePolicy決策樹如下圖:

    • 如果沒有特殊需求,系統默認的緩存策略已經比較完善了。

      官方文檔對默認緩存策略的說明:如果緩存不存在,則向服務器發起請求;如果緩存存在,且緩存response頭沒有指明每次都必須校驗資源更新,且緩存沒有過期,則系統會直接返回緩存,不會發起請求;如果緩存過期了或者要求每次請求都必須校驗資源更新,則發起一個校驗資源的請求,如果(服務器返回)資源有更新則使用服務器返回的最新數據,如果沒有更新則使用本地緩存。如果沒有特殊需求,系統默認的緩存策略已經比較完善了。

  • 客戶端使用系統緩存

  1. 設置緩存策略,決定是否使用緩存(即使允許加載緩存,離線的時候,也只能顯示頁面,具體的數據緩存需要web端實現);

  2. 使用 NSURLProtocol 攔截js、css,圖片資源,但這種方式有一個問題,NSURLProtocol使用了私有API,有審核被拒的風險,項目中暫不推薦使用;

  3. 同服務器進行交互(緩存過期處理,以及web資源更新)。

    WKWebView默認緩存策略遵循HTTP緩存協議,客戶端默認緩存行為實際上是由服務器控制的,客戶端和服務器通過HTTP請求頭和響應頭中的緩存字段來交流,進而影響客戶端的行為。下面幾個相關的請求頭和響應頭需要知道:

    • Cache-Control:max-age=xxxx,指明緩存過期時間

在第一次請求到服務器資源的時候,服務器需要使用Cache-Control這個響應頭來指定緩存策略,它的格式如下:Cache-Control:max-age=xxxx,這個頭指明緩存過期的時間

    • Last-Modified/If-Modified-Since,標識資源最后修改時間

Last-Modified 是由服務器返回響應頭,標識資源的最后修改時間.
If-Modified-Since 則由客戶端發送,標識客戶端所記錄的,資源的最后修改時間。服務器接收到帶有該請求頭的請求時,會使用該時間與資源的最后修改時間進行對比,如果發現資源未被修改過,則直接返回HTTP 304而不返回包體,告訴客戶端直接使用本地的緩存。否則響應完整的消息內容。

    • Etag/If-None-Match,標識資源是否更新

Etag 由服務器發送,告之當資源在服務器上的一個唯一標識符。
客戶端請求時,如果發現資源過期(使用Cache-Control的max-age),發現資源具有Etag聲明,這時請求服務器時則帶上If-None-Match頭,服務器收到后則與資源的標識進行對比,決定返回200或者304。 

  • 設置緩存策略代碼:

    // 默認緩存策略 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] 
       cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15];
  • 客戶端WebView加載H5和服務器交互過程流程圖:

  • WKWebView緩存沙盒路徑:

  • WKWebView清除緩存

    WKWebView,在iOS9以后提供了緩存管理類WKWebsiteDataStore,iOS9以前只能手動移除文件

    WKWebsiteDataStore 提供了API獲取web緩存數據類型

    [WKWebsiteDataStore allWebsiteDataTypes]; 
  • WKWebView支持的緩存類型:

     /**
        清除WKWebView的緩存
        在磁盤緩存上。
        WKWebsiteDataTypeDiskCache,
        
        html離線Web應用程序緩存。
        WKWebsiteDataTypeOfflineWebApplicationCache,
        
        內存緩存。
        WKWebsiteDataTypeMemoryCache,
        
        本地存儲。
        WKWebsiteDataTypeLocalStorage,
        
        Cookies
        WKWebsiteDataTypeCookies,
        
        會話存儲
        WKWebsiteDataTypeSessionStorage,
        
        IndexedDB數據庫。
        WKWebsiteDataTypeIndexedDBDatabases,
        
        查詢數據庫。
        WKWebsiteDataTypeWebSQLDatabases
        */
  • WKWebView 清除指定類型緩存:

    NSSet *websiteDataTypes= [NSSet setWithArray:@[
    
                            WKWebsiteDataTypeDiskCache,
                            WKWebsiteDataTypeMemoryCache
                            ]];
    
    //清除所有的web信息
    //NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
    NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{
    
    }];
  • 拓展閱讀:

    蘋果官方文檔

    WKWebView默認緩存策略與HTTP緩存協議

    iOS WKWebView (NSURLProtocol)攔截js、css,圖片資源

    iOS網絡緩存掃盲篇--使用兩行代碼就能完成80%的緩存需求

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM