星空网 > 软件开发 > 操作系统

iOS网络——NSURLCache设置网络请求缓存

今天在看HTTP协议,看到了response头中的cache-control,于是就深入的研究了一下。发现了iOS中一个一直被我忽略的类——NSURLCache类。

 

NSURLCache

NSURLCache用于缓存网络请求,也就是NSURLRequest,然后根据我们设置的NSURLCache策略进行相应的缓存。

首先介绍一下各种策略

策略意义

UseProtocolCachePolicy

 默认行为
 ReloadIgnoringLocalCacheData 不使用缓存
 ReloadIgnoringLocalAndRemoteCacheData* 我是认真地,不使用任何缓存
 ReturnCacheDataElseLoad 使用缓存(不管它是否过期),如果缓存中没有,那从网络加载吧
 ReturnCacheDataDontLoad 离线模式:使用缓存(不管它是否过期),但是从网络加载
 ReloadRevalidatingCacheData*在使用前去服务器验证 

其中ReloadIgnoringLocalAndRemoteCacheData和ReloadRevalidatingCacheData两种是没有实现的,可以不看。

在创建对request使用cache的时候会让我们选择以上的某种策略进行,也就是

+ (instancetype)requestWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval;

该方法让我们设置策略和时间,然后request会根据策略和时间来进行相应的调度。

 

感受NSURLCache

这里使用默认的缓存策略ReturnCacheDataElseLoad缓存策略,

首先需要创建NSURLCache类

NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:0 diskPath:nil];[NSURLCache setSharedURLCache:URLCache];

1.这里可以看到,创建参数我们制定了 4 * 1024 * 1024的内存(4MB) ,没有使用磁盘空间。

2.NSURLCache使用[NSURLCache sharedURLCache]创建默认的的缓存行为,默认为 4(MB) 内存和 20(MB)磁盘空间,这里我们使用自定义的,所以要setSharedCache。

然后创建request和connection进行请求

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://172.16.25.44/test1.php"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:3];connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];[connection start];

实现NSURLConnectionDelegate协议

-(void)connectionDidFinishLoading:(NSURLConnection *)connection{  NSLog(@"finish");}

然后运行开一下请求,这里用的工具是Charles

iOS网络——NSURLCache设置网络请求缓存images/loading.gif' data-original="http://images0.cnblogs.com/blog2015/717519/201508/040928134083171.png" />

可以看到只有一次请求,再看控制台输出

2015-08-04 09:29:55.297 requestCache[19405:6375355] finish2015-08-04 09:29:55.301 requestCache[19405:6375355] finish2015-08-04 09:29:55.310 requestCache[19405:6375355] finish2015-08-04 09:29:55.451 requestCache[19405:6375355] finish2015-08-04 09:29:55.618 requestCache[19405:6375355] finish2015-08-04 09:29:55.784 requestCache[19405:6375355] finish2015-08-04 09:29:55.984 requestCache[19405:6375355] finish2015-08-04 09:29:56.120 requestCache[19405:6375355] finish

所以说多次的请求只会进行一次请求,因为在内存中NSURLCache为我们缓存了一份response,一旦有同样请求就会使用缓存。

 

缓存持久化

缓存如果设定本地磁盘就会为我们自动进行持久化,修改NSURLCache创建代码

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

设置了20MB的本地磁盘,然后运行程序,进行请求发现还是请求一次没有变化。但是在次运行程序进行请求就会发现,一次远程请求也不会进行了!

打开沙盒,发现在 Library/Caches/bundleId+项目名/下面有三个文件

iOS网络——NSURLCache设置网络请求缓存

这不就是sqlite么!原来NSURLCache帮我们用sqlite将请求存入了数据库,然后当有相同请求时就会调用缓存!

可以想到webView如果加载一个静态页面不用只用请求一次,并且在效果要更新的时候远程请求会有多爽!

 

默认策略

默认策略是 UseProtocolCachePolicy 从字面上来看是说,使用协议缓存策略,但是什么是协议缓存策略呢?

在HTTP协议的response头中,有一个字段是cache-control,由服务器来告诉客户端如何使用缓存。

下面是一个response头

iOS网络——NSURLCache设置网络请求缓存

 

可以看到cache-control指定的行为是public,max-age=5

这里先介绍一下各种指令

iOS网络——NSURLCache设置网络请求缓存

对应上表,可以看出了刚才响应头是要求缓存所有内容,缓存5秒失效,5秒后还要请求远程服务器。

对应PHP就是header("Cache-Control:public,max-age=5");

 

伪造响应

如果我们想让一些请求,有特定的响应,我们可以自己来制作响应

  NSLog(@"%@",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]);      NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://172.16.25.44/test1.php"] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:3];  NSURLCache * cache = [NSURLCache sharedURLCache];    NSData *contentData = [@"123" dataUsingEncoding:NSUTF8StringEncoding];    NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[NSURL URLWithString:@"http://172.16.25.44/test1.php"] MIMEType:@"text/html" expectedContentLength:1000 textEncodingName:@"UTF-8"];  NSCachedURLResponse *cacheRespone = [[NSCachedURLResponse alloc] initWithResponse:response data:contentData];    [cache storeCachedResponse:cacheRespone forRequest:request];    connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];  [connection start];

如上代码,创建了一个针对@"http://172.16.25.44/test1.php"请求的响应,并且让 cache 对该响应进行了存储。

实现

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{  NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];  NSLog(@"%@",dataString);}

输出结果如下

2015-08-04 09:48:58.825 requestCache[19503:6441561] 1232015-08-04 09:48:58.826 requestCache[19503:6441561] finish2015-08-04 09:48:58.983 requestCache[19503:6441561] 1232015-08-04 09:48:58.984 requestCache[19503:6441561] finish2015-08-04 09:48:59.167 requestCache[19503:6441561] 1232015-08-04 09:48:59.167 requestCache[19503:6441561] finish2015-08-04 09:48:59.334 requestCache[19503:6441561] 1232015-08-04 09:48:59.335 requestCache[19503:6441561] finish

可以看到输出的是我们自定义的123,而不是服务器返回的1。

 

修改响应内容

修改响应内容需要我们实现NSURLConnectionDataDelegate 协议并实现

-(NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse{  NSMutableData *mutableData = [[cachedResponse data] mutableCopy];    //添加数据    NSCachedURLResponse *response = [[NSCachedURLResponse alloc] initWithResponse:cachedResponse.response data:mutableData];  return response;}

应为 NSCachedURLResponse 的属性都是readonly的,所以我们想要添加内容就要创建一个可变副本增减内容。

 




原标题:iOS网络——NSURLCache设置网络请求缓存

关键词:IOS

IOS
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

特殊物品不再“特殊”!:https://www.kjdsnews.com/a/1356090.html
Pinterest引流素材最新最热的有哪些?看这一篇全get!:https://www.kjdsnews.com/a/1356091.html
最详细的亚马逊欧代备案指南:https://www.kjdsnews.com/a/1356092.html
奋“发”图强!中国假发畅销海外,狂赚百亿!:https://www.kjdsnews.com/a/1356093.html
2023年海外视觉营销的5大趋势!别再错过了!:https://www.kjdsnews.com/a/1356094.html
实操分享:说说海外销售如何提升个体社媒获客效率、获得高人气:https://www.kjdsnews.com/a/1356095.html
NRA账户的开户主体包括:香港、美国、新加坡、欧盟等国家的详细解析 :https://www.xlkjsw.com/news/94338.html
湘西游轮六 湘江游轮夜游:https://www.vstour.cn/a/411226.html
相关文章
我的浏览记录
最新相关资讯
海外公司注册 | 跨境电商服务平台 | 深圳旅行社 | 东南亚物流