在移動端,沒有網絡或者網絡狀態極差的情況下是一件比較惱人的事情。為了使用戶擁有較好的用戶體驗,網絡緩存是每個成功app必備的功能之一,其實網絡請求緩存很簡單,但還是寫一篇文章記錄下。
不僅在無網絡時可以使用網絡請求緩存,在有網絡時也可以使用網絡請求來提高響應速率,提高用戶體驗。
什么樣的請求可以被緩存?
在網絡請求中,最常用的就是POST和GET,下面只討論這兩種請求。POST請求不可以被緩存,而get請求可以被緩存,GET請求會將請求的參數構造在url中以?符開始,&符連接不同參數。
例如:
https://www.baidu.com/s?wd=123
上如url中" ?"前是get請求的url , ?后是get請求的攜帶的參數,鍵在"="前,值在"="后。
無網絡時從緩存中獲得GET請求響應
從GET請求的實現方式上來給,給緩存的實現提供了基礎,因為向同一個url發送相同參數的GET請求會直接體現在url上,所以我們可以將相同的url視為同一GET請求。當沒有網絡時,去緩存中查看是否有相應的GET請求,有則將其返回。
我們需要做的就是在網絡暢通時保存已經成功通信的GET請求,可以將其以文件的形式保存在本地。
但是文件的名稱如何定義是個比較頭疼的問題,如果以請求的URL作為文件的名稱顯然不太妥當,因為IE對URL長度的限制是2083字節、Firefox瀏覽器URL的長度限制為65,536個字符、chrome瀏覽器URL最大長度限制為8182個字符等等,這么長的文件名占空間是一點,在做字符串匹配時也非常耗時。所以應當換一種方式,這時使用hash值比較明智,因為hash算法對于輸入的任意長度值會轉變為一個固定長度值輸出。
搞定了文件名我們需要在有網絡時保存成功通信的GET請求:
if (success) {
//如果請求成功 , 回調請求到的數據 , 同時 在這里 做本地緩存
NSString *path = [NSString stringWithFormat:@"%ld.plist", (unsigned long)[url hash]];
// 存儲的沙盒路徑
NSString *path_doc = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
// 歸檔
[NSKeyedArchiver archiveRootObject:responseObject toFile:[path_doc stringByAppendingPathComponent:path]];
success(responseObject);
}
在Objective-C中,我們可以將對象進行歸檔,將GET請求返回的數據以對象的形式保存在文件中,達到緩存的目的。
而當無網絡時,這時去本地緩存上查找是否具有緩存,用新URL的hash值與緩存的URL的hash值做比較。
//發生網絡斷開連接
if ([HFReachabilityManager sharedReachabilityManager].currentReachabilityStatus == NotReachable) {
// 在這里讀取本地緩存
NSString *path = [NSString stringWithFormat:@"%ld.plist", (unsigned long)[url hash]];
NSString *path_doc = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
id result = [NSKeyedUnarchiver unarchiveObjectWithFile:[path_doc stringByAppendingPathComponent:path]];
// [KVNProgress showErrorWithStatus:@"無法連接網絡"];
success(result);
}
這時,就完成了在無網絡時的網絡請求緩存。
喜歡給我的贊吧 :) ??