iOS缓存笔记

Get请求缓存


iOS 5.0开始,支持磁盘缓存,但仅支持 HTTP
iOS 6.0开始,支持 HTTPS 缓存

// 设置网络缓存 - 4M 的内存缓存 20M 的磁盘缓存,使用默认的缓存路径 Caches/bundleId
    NSURLCache *cache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
    // 设置全局缓存
    [NSURLCache setSharedURLCache:cache];

上面的两句基本能解决所有的Get请求缓存,而我在自己的某个项目中,清一色的Post请求😂,这TM就尴尬了
今个看到一篇文章,说的是缓存问题,一想到自己做的缓存,存在问题,问题很大。由于我司对于app这一块,貌似也不是很关注,我也不打算改动了,等真正提BUG再改

逻辑漏洞
1.没有想到缓存过期问题
2.撤销缓存问题,现在是一把加载,这个要改改

首先要知道,POST请求不能被缓存,只有 GET 请求能被缓存。因为从数学的角度来讲,GET 的结果是幂等的,就好像字典里的 key 与 value 就是幂等的,而 POST 不 幂等。缓存的思路就是将查询的参数组成的值作为 key ,对应结果作为value。从这个意义上说,一个文件的资源链接,也叫 GET 请求,下文也会这样看待。

  1. 现在我的做法是,让Post也形成Key - value这种,用YYCache缓存

   NSString * urlStr = [NSString stringWithFormat:@"%@%@",baseUrl,sonURl];
    //处理中文和空格问题
    urlStr = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
    //拼接
    NSString * cacheUrl = [self creatUniqueKeyForMD5:urlStr WithDict:paramterDictionary];
//对应的唯一的Key出来了
 NSString * cacheKey = [SystemUtils md5:cacheUrl];

/**
 *  创建一个key
 *
 *  @param urlStr     网址
 *  @param parameters 参数
 *
 *  @return 网址+参数按照一定规律来形成一个key,从而做缓存的MD5转一下,形成特定字符串key
 */
-(NSString *)creatUniqueKeyForMD5:(NSString *)urlStr WithDict:(NSDictionary *)parameters
{
    if (!parameters) {
        return urlStr;
    }
    /**
     *  1.取出来所有Key
     *  2.排序
     *
     *
     *
     */
//    NSMutableArray * lastArray = [NSMutableArray array];
    NSArray * array = [parameters allKeys];
    NSArray * sortArray = [array sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        
        return obj1>obj2;
    }];
    
   __block  NSString * lastString = urlStr;
    [sortArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        
        
            lastString = [NSString stringWithFormat:@"%@_%@_%@_",lastString,obj,[parameters objectForKey:obj]];
      
        
        
    }];
  
    
 NSLog(@"%@",lastString);
    
    return lastString;
    
    
    
}

YYcache使用

如果有缓存,并且断网(我们的需求,大家也可以直接加载,等刷新数据再刷新)


    //设置YYCache属性
    YYCache *cache = [[YYCache alloc] initWithName:UserYYKitCache];
    
    cache.memoryCache.shouldRemoveAllObjectsOnMemoryWarning = YES;
    cache.memoryCache.shouldRemoveAllObjectsWhenEnteringBackground = YES;
    
    id cacheData;
    BadNetWork * badWork = [BadNetWork sharedInstance];
    
    if (isCache) {
        
        //根据网址从Cache中取数据
        cacheData = [cache objectForKey:cacheKey];
        
        
        if (cacheData != 0 &&badWork.isConnectNetWork == NO) {
            //将数据统一处理 //如果没有网络并且存在缓存,则加载缓存
            [self returnDataWithRequestData:cacheData Success:^(NSDictionary *requestDic, NSString *msg) {
                YYLog(@"缓存数据\n\n    %@    \n\n",requestDic);
                successed(requestDic);
            } failure:^(NSString *errorInfo) {
                YYLog(@"缓存失败");
                
            }];
            
            
        }
    }  

问题来了》》》缓存失效了怎么办?

完全没考虑好缓存过期问题?等我研究好再来补充。。。待续

仔细看完文章后,来了解两个概念

1.Last-Modified

在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是客户端请求的资源,同时有一个Last-Modified的属性标记此文件在服务器端最后被修改的时间。

Last-Modified格式类似这样:
Last-Modified : Fri , 12 May 2006 18:53:33 GMT
客户端第二次请求此URL时,根据HTTP协议的规定,浏览器会向服务器传送If-Modified-Since报头,询问该时间之后文件是否有被修改过:
If-Modified-Since : Fri , 12 May 2006 18:53:33 GMT
如果服务器端的资源没有变化,则自动返回 HTTP 304(Not Changed.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。

请求头 响应头
Last-Modified If-Modified-Since

根据实际情况,让你们后台返回这些参数,然后判断即可,如果修改了,这返回HTTP304(Not Changed.)状态码,内容为空,这样就节省了传输数据量。

1.发送请求带上
[request setValue:Modified_value forHTTPHeaderField:@"If-Modified-Since"];

2.收到状态码

3.存储下value
实际上根据自己的来存下
AFN的response在:
 YYLog(@" NSURLSessionDataTask:%@",task.response);

task.response找到Last-Modified用你的方式存储,下次请求的时候,Modified_value的值就是现在你存的

2.ETag(类似我们控制app登录的token,唯一性)

HTTP协议规格说明定义ETag为“被请求变量的实体值”。另一种说法是,ETag是一个可以与Web资源关联的记号(token)。典型的Web资源可以一个Web页,但也可能是JSON或XML文档。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端,以下是服务器端返回的格式:ETag:"50b1c1d4f775c61:df3"客户端的查询更新格式是这样的:If-None-Match : W / "50b1c1d4f775c61:df3"如果ETag没改变,则返回状态304然后不返回,这也和Last-Modified一样。测试Etag主要在断点下载时比较有用。

思路参考Last-Modified,其中的区别,你可以参考文章
链接

本文大量参考这篇文章,谢谢@ChenYilong

概念性解释来源于😂百度百科😂

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352

推荐阅读更多精彩内容