美文网首页JS 与 iOS缓存
NSURLCache使用和UIWebView URL 拦截

NSURLCache使用和UIWebView URL 拦截

作者: Joe_lisa | 来源:发表于2016-02-20 16:21 被阅读1774次

    现在因为项目需要更新版本,采用缓存的策略要发生改变。之前的版本在展示新闻后台返回的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

    相关文章

      网友评论

      • gqlx_sza:不支持代码吗? MarkDown 不支持代码?
      • louisly:“iOS8下面遇到的操蛋问题就是把NSURlCache必须设置在程序启动时才能有效”
        真的是很操蛋!研究的半天,才发现这个坑。
        所以索性把方法放到load里了
        + (void)load {
        [NSURLCache setSharedURLCache:[LYURLCache new]];
        }
      • 小鲲鹏:可以私聊一下 373477038 谢谢大神
      • 小鲲鹏:请问在github上有相应的开源的吗 谢谢分享
      • 来宝:你好大神,这个有demo吗,发我看看

      本文标题:NSURLCache使用和UIWebView URL 拦截

      本文链接:https://www.haomeiwen.com/subject/srevkttx.html