- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
//2M(内存空间)和200M(磁盘空间) cacheTime:过期时间置为0:表示没有过期时间
CustomNSURLCache *urlCache = [[CustomNSURLCachealloc] initWithMemoryCapacity:2 *1024 * 1024
diskCapacity:200 * 1024 * 1024
diskPath:nil
cacheTime:300];
[CustomNSURLCache setSharedURLCache:urlCache];
return YES;
}
- (void)viewDidLoad {
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(@"-- %@",NSHomeDirectory());
UIWebView *WebView = [[UIWebViewalloc]initWithFrame:self.view.frame];
WebView.delegate = self;
self.web = WebView;
[self.webloadRequest:[NSURLRequestrequestWithURL:[NSURLURLWithString:@"http://www.iqiyi.com"]]];
[self.viewaddSubview:_web];
}
- (void)didReceiveMemoryWarning {
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
CustomNSURLCache *urlCache = (CustomNSURLCache *)[NSURLCachesharedURLCache];
[urlCache removeAllCachedResponses];
}
#import <Foundation/Foundation.h>
#import "Util.h"
@interface CustomNSURLCache : NSURLCache
/**
* 过期时间
*/
@property(nonatomic,assign) NSInteger cacheTime;
/**
* 存储路径
*/
@property(nonatomic,retain) NSString *diskPath;
@property(nonatomic,retain) NSMutableDictionary *responseDictionary;
/**
*
* @param memoryCapacity 内存空间
* @param diskCapacity 磁盘空间
* @param path 存储路径(默认:Library>>Caches>>URLCACHE)
* @param cacheTime 过期时间
*/
- (id)initWithMemoryCapacity:(NSUInteger)memoryCapacity diskCapacity:(NSUInteger)diskCapacity diskPath:(NSString *)path cacheTime:(NSInteger)cacheTime;
@end
#import "CustomNSURLCache.h"
#import "Reachability.h"
@interface CustomNSURLCache(private)
- (NSString *)cacheFolder;
- (NSString *)cacheFilePath:(NSString *)file;
- (NSString *)cacheRequestFileName:(NSString *)requestUrl;
- (NSString *)cacheRequestOtherInfoFileName:(NSString *)requestUrl;
- (NSCachedURLResponse *)dataFromRequest:(NSURLRequest *)request;
- (void)deleteCacheFolder;
@end
@implementation CustomNSURLCache
@synthesize cacheTime = _cacheTime;
@synthesize diskPath = _diskPath;
@synthesize responseDictionary = _responseDictionary;
/**
*
* @param memoryCapacity 内存空间
* @param diskCapacity 磁盘空间
* @param path 存储路径(默认:Library>>Caches>>URLCACHE)
* @param cacheTime 过期时间
*/
- (id)initWithMemoryCapacity:(NSUInteger)memoryCapacity diskCapacity:(NSUInteger)diskCapacity diskPath:(NSString *)path cacheTime:(NSInteger)cacheTime {
if (self = [selfinitWithMemoryCapacity:memoryCapacity diskCapacity:diskCapacity diskPath:path]) {
self.cacheTime = cacheTime;
if (path)
self.diskPath = path;
else
self.diskPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES)lastObject];
self.responseDictionary = [NSMutableDictionarydictionaryWithCapacity:0];
}
return self;
}
/**
* 判断是否为GET请求或者 POST请求
*/
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request {
if ([request.HTTPMethodcompare:@"GET"] !=NSOrderedSame) {
return [supercachedResponseForRequest:request];
}
// NSSet *supportSchemes = [[NSSet setWithObjects:@"http", @"https", @"ftp", nil] retain];
// NSURL *url = request.URL;
// if (![supportSchemes containsObject:url.scheme]) {
// [supportSchemes release];
// return [self dataFromRequest:request];
// }
return [selfdataFromRequest:request];
}
- (void)removeAllCachedResponses {
[superremoveAllCachedResponses];
[selfdeleteCacheFolder];
}
/**
* 重写系统的方法,移除本地存储的过期文件
* @param request 请求
*/
- (void)removeCachedResponseForRequest:(NSURLRequest *)request {
[superremoveCachedResponseForRequest:request];
NSString *url = request.URL.absoluteString;
NSString *fileName = [selfcacheRequestFileName:url];
NSString *otherInfoFileName = [selfcacheRequestOtherInfoFileName:url];
NSString *filePath = [selfcacheFilePath:fileName];
NSString *otherInfoPath = [selfcacheFilePath:otherInfoFileName];
NSFileManager *fileManager = [NSFileManagerdefaultManager];
[fileManager removeItemAtPath:filePath error:nil];
[fileManager removeItemAtPath:otherInfoPatherror:nil];
}
#pragma mark - custom url cache
/**
* 文件夹名字
*
* @return URLCACHE
*/
- (NSString *)cacheFolder {
return@"URLCACHE";
}
/**
* 删除文件夹
*/
- (void)deleteCacheFolder {
NSString *path = [NSStringstringWithFormat:@"%@/%@",self.diskPath, [selfcacheFolder]];
NSFileManager *fileManager = [NSFileManagerdefaultManager];
[fileManager removeItemAtPath:path error:nil];
}
/**
* @param file 文件名字
*
* @return 文件路径
*/
- (NSString *)cacheFilePath:(NSString *)file {
NSString *path = [NSStringstringWithFormat:@"%@/%@",self.diskPath, [selfcacheFolder]];
NSFileManager *fileManager = [NSFileManagerdefaultManager];
BOOL isDir;
if ([fileManager fileExistsAtPath:path isDirectory:&isDir] && isDir) {
} else {
[fileManager createDirectoryAtPath:pathwithIntermediateDirectories:YESattributes:nilerror:nil];
}
return [NSStringstringWithFormat:@"%@/%@", path, file];
}
/**
* 将请求地址进行MD5加密
*
* @param requestUrl 请求地址
*
* @return 返回一个字符串
*/
- (NSString *)cacheRequestFileName:(NSString *)requestUrl {
return [Utilmd5Hash:requestUrl];
}
- (NSString *)cacheRequestOtherInfoFileName:(NSString *)requestUrl {
return [Utilmd5Hash:[NSStringstringWithFormat:@"%@-otherInfo", requestUrl]];
}
/**
* 有请求时都会调用此方法,在此方法中进行保存request信息NSURLRequest为只读的
*
* @param request 请求的 NSURLRequest
*
* @return
*/
- (NSCachedURLResponse *)dataFromRequest:(NSURLRequest *)request {
NSString *url = request.URL.absoluteString;
NSString *fileName = [selfcacheRequestFileName:url];
NSString *otherInfoFileName = [selfcacheRequestOtherInfoFileName:url];
NSString *filePath = [selfcacheFilePath:fileName];
NSString *otherInfoPath = [selfcacheFilePath:otherInfoFileName];
NSDate *date = [NSDatedate];
NSFileManager *fileManager = [NSFileManagerdefaultManager];
if ([fileManager fileExistsAtPath:filePath]) {
BOOL expire = false;
NSDictionary *otherInfo = [NSDictionarydictionaryWithContentsOfFile:otherInfoPath];
if (self.cacheTime >0) {
NSInteger createTime = [[otherInfoobjectForKey:@"time"]intValue];
//判断时间是否过期,是否需要重新加载资源
if (createTime + self.cacheTime < [date timeIntervalSince1970]) {
expire = true;
}
}
if (expire == false) {
NSLog(@"data from cache ...");
//获取本地文件
NSData *data = [NSDatadataWithContentsOfFile:filePath];
//初始化一个Response里边的data为磁盘中保存的data
NSURLResponse *response = [[NSURLResponsealloc] initWithURL:request.URL
MIMEType:[otherInfo objectForKey:@"MIMEType"]
expectedContentLength:data.length
textEncodingName:[otherInfo objectForKey:@"textEncodingName"]];
NSCachedURLResponse *cachedResponse = [[NSCachedURLResponsealloc] initWithResponse:responsedata:data];
return cachedResponse;
} else {
//移除之前磁盘中缓存过期的文件
[fileManager removeItemAtPath:filePatherror:nil];
[fileManager removeItemAtPath:otherInfoPatherror:nil];
}
}
//网络断开则返回
if (![ReachabilitynetworkAvailable]) {
return nil;
}
__block NSCachedURLResponse *cachedResponse =nil;
//sendSynchronousRequest请求也要经过NSURLCache
id boolExsite = [self.responseDictionaryobjectForKey:url];
if (boolExsite == nil) {
[self.responseDictionarysetValue:[NSNumbernumberWithBool:TRUE]forKey:url];
//发送请求
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueuealloc] init]completionHandler:^(NSURLResponse *response,NSData *data,NSError *error)
{
//判断是否存在数据
if (response && data) {
//删除内存中之前的数据,使用新的数据
[self.responseDictionaryremoveObjectForKey:url];
if (error) {
NSLog(@"error : %@", error);
NSLog(@"not cached: %@", request.URL.absoluteString);
cachedResponse = nil;
}
NSLog(@"cache url --- %@ ",url);
//save to cache 保存
NSDictionary *dict = [NSDictionarydictionaryWithObjectsAndKeys:[NSStringstringWithFormat:@"%f", [datetimeIntervalSince1970]], @"time",
response.MIMEType,@"MIMEType",
response.textEncodingName,@"textEncodingName", nil];
//写入文件
[dict writeToFile:otherInfoPathatomically:YES];
[data writeToFile:filePath atomically:YES];
/**
把更改过后的 response
映射关系:
NSURLRequest --------> NSCachedURLResponse
*/
cachedResponse = [[NSCachedURLResponsealloc] initWithResponse:responsedata:data];
}
}];
return cachedResponse;
//NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
}
return nil;
}
@end