在移动端,没有网络或者网络状态极差的情况下是一件比较恼人的事情。为了使用户拥有较好的用户体验,网络缓存是每个成功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);
}
这时,就完成了在无网络时的网络请求缓存。
喜欢给我的赞吧 :) ❤️