JS 与 iOS缓存

NSURLCache使用和UIWebView URL 拦截

2016-02-20  本文已影响1774人  Joe_lisa

现在因为项目需要更新版本,采用缓存的策略要发生改变。之前的版本在展示新闻后台返回的html内容所以之前的缓存策略只需要将html内容写入到文件中即可。现在新版本新闻详情的内容变得更加的复杂多样,所以现在直接的采用网页展示,也就是后台只会返回一个链接,至于UIwebView的缓存就需要自己去重新的定义了。

查了很多的博客和文档,发现webView本身是由缓存的,也就是NSURLCache,但是NSURLCache不满足需求,所以只能自己去定义。官方对NSURLCache虽然说是内存缓存和磁盘缓存相结合的,实际上只有内存缓存而且只有4M,另外就是现在混存的趋势时,定时清理,所以必须自己去复写NSURLCache来实现更多的需求。

(-)方法介绍

首先,看看NSURLCache的一些方法介绍:

初始化相关的几个方法:sharedURLCache;setSharedURLCache;initWithMemoryCapacity

(1) sharedURLCache方法返回一个NSURLCache实例。

默认情况下,内存是4M,4* 1024 * 1024;Disk为20M,20 * 1024 * 1024;路径在(NSHomeDirectory)/Library/Caches/(current application name, [[NSProcessInfo processInfo] processName])

(2)setSharedURLCache 可以通过这个方法来改变默认的NSURLCache。

(3)通过initWithMemoryCapacity 来定制自己的NSURLCache

cache使用相关的几个方法:

cachedResponseForRequest;//缓存请求

storeCachedResponse;//存储缓存

removeCachedResponseForRequest;//删除缓存请求

removeAllCachedResponses;//删除所以缓存请求

- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request

//如果对应的NSURLRequest没有cached的response那么返回nil

- (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request;

//为特定的NSURLRequest做cache

- (void)removeCachedResponseForRequest:(NSURLRequest *)request;

//移除特定NSURLRequest的cache

- (void)removeAllCachedResponses;

//移除所有的cache

(二)自定义cache

我们这边的需求将所有的数据写入到文件中,过期后将数据清除掉。所以我这里只需要重写

- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)reques

这个方法即可

下面是核心代码:

#pragma mark - super

-(NSCachedURLResponse

*)cachedResponseForRequest:(NSURLRequest*)request{

if ([request.HTTPMethod compare:@"GET"] != NSOrderedSame) {

return [super cachedResponseForRequest:request];

}

return [self customResponseForRequest:request];

}

#pragma mark - private

-(NSString *)getFileName:(NSString *)url{

return [url getMd5_32Bit];

}

-(NSString *)getOtherInfoName:(NSString *)url{

return [[NSString stringWithFormat:@"%@-otherInfo",url] getMd5_32Bit];

}

- (NSString *)cacheFilePath:(NSString *)fileName{

NSString *filePath = [NSStringstringWithFormat:@"URLCache/%@",fileName];

NSString*path = kFilePathAtCachWithName(filePath);

NSFileManager *fileManager = [NSFileManager defaultManager];

BOOL isDir;

if([fileManager fileExistsAtPath:path isDirectory:&isDir] && isDir) {

} else{

[fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];

}

return path;

}

-(NSCachedURLResponse*)customResponseForRequest:(NSURLRequest*)request{

​NSString *url = request.URL.absoluteString;//请求的链接

NSString*fileName = [self getFileName:url];//缓存的文件名

NSString*otherInfoName = [self getOtherInfoName:url];//缓存信息的文件名

NSString*filePath = [self cacheFilePath:fileName];//缓存的目录路径

NSString*otherInfoPath = [self cacheFilePath:otherInfoName];//缓存信息字典路径

​NSFileManager *fileManger = [NSFileManager defaultManager];

if ([fileManger fileExistsAtPath:filePath]) {

​//当文件名存在的时候

NSDate*date = [NSDate date];

BOOL isOverdue = YES;

NSDictionary *dicInfo = [NSDictionarydictionaryWithContentsOfFile:otherInfoPath];

if(self.catchTime > 0 && dicInfo) {

NSDate*createDate = dicInfo[kTimeKey];

double createTime = [date timeIntervalSinceDate:createDate];

if (createTime < self.catchTime) {

isOverdue = NO;

}

}

if (!isOverdue) {

//

没有过期

//            NSLog(@"访问缓存数据

..");

NSData *data = [NSDatadataWithContentsOfFile:filePath];

NSURLResponse *response = [[NSURLResponse alloc] initWithURL:request.URL MIMEType:dicInfo[kMIMETypeKey] expectedContentLength:data.lengthtextEncodingName:dicInfo[kTextEncodingNameKey]];

NSCachedURLResponse *cacheResponse = [[NSCachedURLResponsealloc] initWithResponse:response data:data];

return cacheResponse;

}else{

//已经过期删除信息

[fileManger removeItemAtPath :filePath error:nil];

[fileManger removeItemAtPath :otherInfoPath error:nil];

}

}

BOOL isExsit = [[self.dicResponse objectForKey:url] boolValue];

if (!isExsit) {

[self .dicResponse setObject:@(YES) forKey:url];

//        NSLog(@"网络请求数据...");

__block NSCachedURLResponse *cacheResponse = nil;

[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse*response, NSData *data, NSError *connectionError) {

//移除请求记录

[self .dicResponse removeObjectForKey:url];

if (data && response) {

NSMutableDictionary *dicInfo = [NSMutableDictionarydictionary];

[dicInfo setObject :[NSDate date] forKey:kTimeKey];

[dicInfo setObject :kUnNilStr(response.MIMEType) forKey:kMIMETypeKey];

[dicInfo setObject :kUnNilStr(response.textEncodingName) forKey:kTextEncodingNameKey];

BOOL state = [data writeToFile:filePath atomically:NO];

NSLog(@"%d",state);

[dicInfo writeToFile :otherInfoPath atomically:YES];

cacheResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:data];

}

}];

return cacheResponse;

}else{

//        NSLog(@"该请求已存在

...");

}

return nil;

}

ps: 这操蛋的博客,居然不支持代码格式,看上去怪怪的。

另外还可针对不同的请求来缓存,因为现在还没有这个需求,所以现在就没有添加进去。有不足的地方希望能收到更多的宝贵意见。

ps:ios8下面遇到的操蛋问题就是把NSURlCache必须设置在程序启动时才能有效,另外就是要区分非web的请求,只要在请求头中设置个判断的标志即可。此处不知道查了多少英文文档才知道这么点

本文链接http://blog.sina.com.cn/s/blog_7da8833c0102w2q7.html  在开始看iOS UIWebView URL拦截,看到这里,顺便就整理下http://www.cocoachina.com/ios/20150626/12161.html?utm_source=tuicool&utm_medium=referral

上一篇下一篇

猜你喜欢

热点阅读