在移動端壕翩,沒有網(wǎng)絡或者網(wǎng)絡狀態(tài)極差的情況下是一件比較惱人的事情澜汤。為了使用戶擁有較好的用戶體驗稠诲,網(wǎng)絡緩存是每個成功app必備的功能之一,其實網(wǎng)絡請求緩存很簡單飒炎,但還是寫一篇文章記錄下埋哟。
不僅在無網(wǎng)絡時可以使用網(wǎng)絡請求緩存,在有網(wǎng)絡時也可以使用網(wǎng)絡請求來提高響應速率郎汪,提高用戶體驗赤赊。
什么樣的請求可以被緩存?
在網(wǎng)絡請求中煞赢,最常用的就是POST和GET,下面只討論這兩種請求抛计。POST請求不可以被緩存,而get請求可以被緩存照筑,GET請求會將請求的參數(shù)構造在url中以?符開始吹截,&符連接不同參數(shù)。
例如:
https://www.baidu.com/s?wd=123
上如url中" 凝危?"前是get請求的url , ?后是get請求的攜帶的參數(shù)波俄,鍵在"="前,值在"="后蛾默。
無網(wǎng)絡時從緩存中獲得GET請求響應
從GET請求的實現(xiàn)方式上來給懦铺,給緩存的實現(xiàn)提供了基礎,因為向同一個url發(fā)送相同參數(shù)的GET請求會直接體現(xiàn)在url上支鸡,所以我們可以將相同的url視為同一GET請求冬念。當沒有網(wǎng)絡時,去緩存中查看是否有相應的GET請求牧挣,有則將其返回刘急。
我們需要做的就是在網(wǎng)絡暢通時保存已經(jīng)成功通信的GET請求,可以將其以文件的形式保存在本地浸踩。
但是文件的名稱如何定義是個比較頭疼的問題叔汁,如果以請求的URL作為文件的名稱顯然不太妥當,因為IE對URL長度的限制是2083字節(jié)检碗、Firefox瀏覽器URL的長度限制為65,536個字符据块、chrome瀏覽器URL最大長度限制為8182個字符等等,這么長的文件名占空間是一點折剃,在做字符串匹配時也非常耗時另假。所以應當換一種方式,這時使用hash值比較明智怕犁,因為hash算法對于輸入的任意長度值會轉變?yōu)橐粋€固定長度值輸出边篮。
搞定了文件名我們需要在有網(wǎng)絡時保存成功通信的GET請求:
if (success) {
//如果請求成功 , 回調請求到的數(shù)據(jù) , 同時 在這里 做本地緩存
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請求返回的數(shù)據(jù)以對象的形式保存在文件中戈轿,達到緩存的目的凌受。
而當無網(wǎng)絡時,這時去本地緩存上查找是否具有緩存思杯,用新URL的hash值與緩存的URL的hash值做比較胜蛉。
//發(fā)生網(wǎng)絡斷開連接
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:@"無法連接網(wǎng)絡"];
success(result);
}
這時,就完成了在無網(wǎng)絡時的網(wǎng)絡請求緩存色乾。
喜歡給我的贊吧 :) ??