Skip to content

Latest commit

 

History

History
50 lines (40 loc) · 3.44 KB

网络请求缓存之无网络.md

File metadata and controls

50 lines (40 loc) · 3.44 KB

在移动端,没有网络或者网络状态极差的情况下是一件比较恼人的事情。为了使用户拥有较好的用户体验,网络缓存是每个成功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);
    }

这时,就完成了在无网络时的网络请求缓存。

喜欢给我的赞吧 :) ❤️