iOS 网络请求数据缓存

1. NSURLCache简介:

iOS对NSURLRequest提供了7种缓存策略:(实际上能用的只有4种)

NSURLRequestUseProtocolCachePolicy // 默认的缓存策略(取决于协议)

NSURLRequestReloadIgnoringLocalCacheData // 忽略缓存,重新请求

NSURLRequestReloadIgnoringLocalAndRemoteCacheData // 未实现

NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData // 忽略缓存,重新请求

NSURLRequestReturnCacheDataElseLoad// 有缓存就用缓存,没有缓存就重新请求

NSURLRequestReturnCacheDataDontLoad// 有缓存就用缓存,没有缓存就不发请求,当做请求出错处理(用于离线模式)

NSURLRequestReloadRevalidatingCacheData // 未实现

 

NSURLCache的常见用法

(1)获得全局缓存对象(没必要手动创建)NSURLCache *cache = [NSURLCache sharedURLCache]; 

(2)设置内存缓存的最大容量(字节为单位,默认为512KB)- (void)setMemoryCapacity:(NSUInteger)memoryCapacity;

(3)设置硬盘缓存的最大容量(字节为单位,默认为10M)- (void)setDiskCapacity:(NSUInteger)diskCapacity;

(4)硬盘缓存的位置:沙盒/Library/Caches

(5)取得某个请求的缓存- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request; 

(6)清除某个请求的缓存- (void)removeCachedResponseForRequest:(NSURLRequest *)request;

(7)清除所有的缓存- (void)removeAllCachedResponses;

 缓存GET请求

  要想对某个GET请求进行数据缓存,非常简单

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

  // 设置缓存策略

  request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;

  只要设置了缓存策略,系统会自动利用NSURLCache进行数据缓存

 

 缓存的注意事项

缓存的设置需要根据具体的情况考虑,如果请求某个URL的返回数据:

  (1)经常更新:不能用缓存!比如股票、彩票数据

  (2)一成不变:果断用缓存

  (3)偶尔更新:可以定期更改缓存策略 或者 清除缓存

提示:如果大量使用缓存,会越积越大,建议定期清除缓存

 2.借助ETag或Last-Modified判断文件缓存是否有效

 通过打印一个response实例,可以看到response header部分如下所示:

 我们可以在请求数据时先上传Etag或者是Last-Modified让服务器端进行判断,若数据未发生变动则加载本地数据,否则加载服务器端数据。

请求的HeaderValue和响应的HeaderValue如下所示:

 

下面以Etag为例进行数据缓存:

先设置缓存内存和硬盘大小:

NSURLCache *urlCache= [[NSURLCache alloc]initWithMemoryCapacity:4*1024*1024 diskCapacity:20*1024*1024 diskPath:nil];
    
    [NSURLCache setSharedURLCache:urlCache];

下载一张图片:

- (IBAction)download:(UIButton *)sender {
    
    NSURL *url=[NSURL URLWithString:@"http://192.168.1.102:8080/love/images/bg2.jpg"];
    NSMutableURLRequest *mRequest=[NSMutableURLRequest requestWithURL:url];
    mRequest.cachePolicy=NSURLRequestReloadIgnoringCacheData;
    mRequest.timeoutInterval=5;
    // 根据请求获取到`被缓存的响应`!
    NSCachedURLResponse *cacheResponse =  [[NSURLCache sharedURLCache] cachedResponseForRequest:mRequest];
    //cacheResponse不存在时设置etag为空
    if (!cacheResponse) {
        self.etag=nil;
    }
    //发送etag
    if (self.etag.length>0) {
        //NSLog(@"Etag=%@",self.etag);
        [mRequest setValue:self.etag forHTTPHeaderField:@"If-None-Match"];
    }
    
        [NSURLConnection sendAsynchronousRequest:mRequest queue:[NSOperationQueue new] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
            // 类型转换(如果将父类设置给子类,需要强制转换)
            NSHTTPURLResponse *httpResponse=(NSHTTPURLResponse*)response;
           // NSLog(@"res=%@",httpResponse);
            // 判断响应的状态码是否是 304 Not Modified (更多状态码含义解释: https://github.com/ChenYilong/iOSDevelopmentTips
            if (httpResponse.statusCode==304) {
                NSLog(@"加载本地缓存图片");
                // 如果是,使用本地缓存
                // 根据请求获取到`被缓存的响应`!
                NSCachedURLResponse *cacheResponse =  [[NSURLCache sharedURLCache] cachedResponseForRequest:mRequest];
                // 拿到缓存的数据
                data = cacheResponse.data;
                
            }else{
                
                NSLog(@"请求网络端图片");
            }
            
            if(data){
                
                [self performSelectorOnMainThread:@selector(setImage:) withObject:data waitUntilDone:YES];
            }
            
             self.etag=httpResponse.allHeaderFields[@"Etag"];
            
        }];
    
    

  //  NSArray *arr=NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES);
  //  NSString *path=[arr objectAtIndex:0];
   // NSLog(@"%@",path);
}

-(void)setImage:(NSData*)data{
   // NSLog(@"setimage");
     self.imageView.image=[UIImage imageWithData:data];
}

清除所有缓存:

- (IBAction)clearCache:(UIButton *)sender {
    
    [[NSURLCache sharedURLCache] removeAllCachedResponses];

}

 

 

 

 

 

参考文献:

http://www.jianshu.com/p/fb5aaeac06ef

http://www.cnblogs.com/wendingding/p/3950198.html

转载于:https://www.cnblogs.com/sunjianfei/p/5777263.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值