最初我以為:
testCache = [[NSURLCache alloc]initWithMemoryCapacity:1024*1024*12 diskCapacity:1024*1024*120 diskPath:@"Assitant.db"]; [NSURLCache setSharedURLCache:testCache];
就能讓webview自動的控制緩存,沒想到圖片還是每次都在重新加載。實在就想不通了,120M還存不下?不知道是不是我用法沒對。
後來經過一番查閱之後,發現似乎要自己實現緩存的讀寫!於是寫了一個,花了三天時間,開始總是發現似乎寫入成功了,但再進入有沒有了。經過3天才發現是被我自己刪除了,裡面的刪除函數,每次程序啟動都會進行刪除,無語了。
網上的資料確實不少,五花八門,不是過時了,就是不靠譜(此文寫與2014-11-08 22:13,iOS7)。
上代碼,使用方法在最下面。
// // MyUrlCache.h // com.lcst.miniBrowser // // Created by lein on 14-11-5. // Copyright (c) 2014年 lein. All rights reserved. // #import@interface MyUrlCache : NSURLCache - (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request; - (void) storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request; - (void) initilize; - (void) doRemoveAllCachedResponses; @end
// // MyUrlCache.m // com.lcst.miniBrowser // // Created by lein on 14-11-5. // Copyright (c) 2014年 lein. All rights reserved. // #import "MyUrlCache.h" #import "Utils.h" @implementation MyUrlCache #define WILL_BE_CACHED_EXTS ".jpg.png.gif.bmp.ico" #define DEBUGP //#define WILL_BE_CACHED_EXTS ".html" NSString * spath; NSFileManager *fileManager; NSString* dirName=@"httpCache"; NSInteger dirType = 0; -(void) initilize{ fileManager = [NSFileManager defaultManager]; NSArray *paths = NSSearchPathForDirectoriesInDomains((dirType==0?NSDocumentDirectory:(dirType==1?NSLibraryDirectory:NSCachesDirectory)), NSUserDomainMask, YES); spath =[paths objectAtIndex:0]; [fileManager changeCurrentDirectoryPath:spath]; spath = [spath stringByAppendingPathComponent:dirName]; [fileManager changeCurrentDirectoryPath:spath]; } - (void)removeAllCachedResponses{ //這裡不能執行doRemoveAllCachedResponses,否則每次就會刪除你寫入的 } - (void) doRemoveAllCachedResponses{ if (spath!=nil) { [fileManager removeItemAtPath:spath error:nil]; } } - (NSString *) getMineType:(NSURLRequest *)request{ NSString *ext = [[request URL] absoluteString].pathExtension; if(ext!=nil){ NSString* str; if([ext compare:@"htm"]||[ext compare:@"html"]) str = @"text/html"; else str = [NSString stringWithFormat:@"image/%@", ext]; return str; } return @""; } - (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request { NSString* filename = [self getCachedFileName:request]; if(spath!=nil && filename.length>0){ filename = [spath stringByAppendingPathComponent:filename]; if([fileManager fileExistsAtPath:filename]){ #ifdef DEBUGP NSLog(@"\n注意::::Cache used: %@", [[request URL] absoluteString]); #endif NSData* data = [NSData dataWithContentsOfFile:filename]; NSURLResponse *response = [[NSURLResponse alloc] initWithURL:request.URL MIMEType:[self getMineType:request] expectedContentLength:data.length textEncodingName:nil]; NSCachedURLResponse* cachedResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:data]; return cachedResponse; } } return nil; } - (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request { NSString* filename = [self getCachedFileName:request]; if(spath!=nil && filename.length>0){ if(![fileManager fileExistsAtPath:filename]){ filename = [Utils writeFileToDirWithDirType:dirName dirType:dirType fileName:filename DATA:cachedResponse.data]; #ifdef DEBUGP NSLog(@"\n注意::::寫入緩存文件=%@",filename ); #endif } } #ifdef DEBUGP else NSLog(@"\n注意::::不緩存: %@", [[request URL] absoluteString]); #endif } - (NSString*) getCachedFileName:(NSURLRequest *) request{ NSString *ext = [[request URL] absoluteString].pathExtension; if(ext!=nil){ if([@WILL_BE_CACHED_EXTS rangeOfString:ext.lowercaseString].length>0){ return [NSString stringWithFormat:@"%@.%@", [Utils md5:[[request URL] absoluteString]], ext]; } } return @""; } @end
// // Utils.h // com.lcst.miniBrowser // // Created by lein on 14-8-4. // Copyright (c) 2014年 lein. All rights reserved. // #import#import @interface Utils : NSObject +(void) writeFile:(NSString *) filePath data:(NSString *) _data; +(NSString *) readFile:(NSString *) filePath; +(NSString *) md5:(NSString *)str; +(NSString *) replaceStringBetween:(NSString *) startStr EndString:(NSString *) endString Str:(NSString *) str; +(NSInteger)getTs; +(NSData *)uncompressZippedData:(NSData *)compressedData; +(NSString*) writeFileToDirWithDirType:(NSString*) dirname dirType:(NSInteger) type fileName:(NSString*) filename DATA:(NSData *) data; +(NSData*) readFileFromDirWithDirType:(NSString*) dirname dirType:(NSInteger) type fileName:(NSString*) filename; @end
// // Utils.m // com.lcst.miniBrowser // // Created by lein on 14-8-4. // Copyright (c) 2014年 lein. All rights reserved. // #import "Utils.h" #import@implementation Utils +(void) writeFile:(NSString *) filePath data:(NSString *) _data{ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString* fileName = [[paths objectAtIndex:0] stringByAppendingPathComponent:filePath]; // 用這個方法來判斷當前的文件是否存在,如果不存在,就創建一個文件 NSFileManager *fileManager = [NSFileManager defaultManager]; if ( ![fileManager fileExistsAtPath:fileName]) { NSLog(@"File %@ not exists!", fileName); [fileManager createFileAtPath:fileName contents:nil attributes:nil]; }else NSLog(@"File %@ exists!", fileName); NSLog(@"File %@ will write!", fileName); [_data writeToFile:fileName atomically:YES encoding:NSUTF8StringEncoding error:nil]; } +(NSString *) replaceStringBetween:(NSString *) startStr EndString:(NSString *) endString Str:(NSString *) str{ NSRange range1 = [str rangeOfString:startStr]; int len = str.length - range1.location - range1.length; NSRange range2 = [str rangeOfString:endString options:NSCaseInsensitiveSearch range:NSMakeRange(range1.location+range1.length, len)]; int start =range1.length+range1.location; len = range2.location-(range1.length+range1.location); NSString* toReplace = [str substringWithRange:NSMakeRange(start, len)]; return [str stringByReplacingOccurrencesOfString:toReplace withString:@""]; } +(NSString *) readFile:(NSString *) filePath{ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString* fileName = [[paths objectAtIndex:0]stringByAppendingPathComponent:filePath]; NSLog(@"File %@ will be read!", fileName); NSString* myString = [NSString stringWithContentsOfFile:fileName usedEncoding:NULL error:NULL]; return myString; } //md5 32位 加密 (小寫) + (NSString *)md5:(NSString *)srcString { const char *cStr = [srcString UTF8String ]; unsigned char digest[ CC_MD5_DIGEST_LENGTH ]; CC_MD5 ( cStr, (CC_LONG) strlen (cStr), digest ); NSMutableString *result = [ NSMutableString stringWithCapacity : CC_MD5_DIGEST_LENGTH * 2 ]; for ( int i = 0 ; i < CC_MD5_DIGEST_LENGTH ; i++) [result appendFormat : @"%02x" , digest[i]]; return result; } + (NSInteger)getTs{ NSDate *date = [NSDate date]; NSTimeInterval timestamp = [date timeIntervalSince1970]; return (NSInteger) timestamp; } +(NSData *)uncompressZippedData:(NSData *)compressedData{ if ([compressedData length] == 0) return compressedData; unsigned full_length = [compressedData length]; unsigned half_length = [compressedData length] / 2; NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length]; BOOL done = NO; int status; z_stream strm; strm.next_in = (Bytef *)[compressedData bytes]; strm.avail_in = [compressedData length]; strm.total_out = 0; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; if (inflateInit2(&strm, (15+32)) != Z_OK) return nil; while (!done) { // Make sure we have enough room and reset the lengths. if (strm.total_out >= [decompressed length]) { [decompressed increaseLengthBy: half_length]; } strm.next_out = [decompressed mutableBytes] + strm.total_out; strm.avail_out = [decompressed length] - strm.total_out; // Inflate another chunk. status = inflate (&strm, Z_SYNC_FLUSH); if (status == Z_STREAM_END) { done = YES; } else if (status != Z_OK) { break; } } if (inflateEnd (&strm) != Z_OK) return nil; // Set real length. if (done) { [decompressed setLength: strm.total_out]; return [NSData dataWithData: decompressed]; } else { return nil; } } +(NSString*) writeFileToDirWithDirType:(NSString*) dirname dirType:(NSInteger) type fileName:(NSString*) filename DATA:(NSData *) data{ NSFileManager* fileManager = [NSFileManager defaultManager]; NSArray *paths = NSSearchPathForDirectoriesInDomains((type==0?NSDocumentDirectory:(type==1?NSLibraryDirectory:NSCachesDirectory)), NSUserDomainMask, YES); NSString* spath =[paths objectAtIndex:0]; [fileManager changeCurrentDirectoryPath:spath]; if(dirname.length>0){ [fileManager createDirectoryAtPath:dirname withIntermediateDirectories:YES attributes:nil error:nil]; spath = [NSString stringWithFormat:@"%@/%@/%@", spath, dirname, filename]; }else spath = [NSString stringWithFormat:@"%@/%@", spath, filename]; [fileManager createFileAtPath:spath contents:data attributes:nil]; return spath; } +(NSData*) readFileFromDirWithDirType:(NSString*) dirname dirType:(NSInteger) type fileName:(NSString*) filename{ NSArray *paths = NSSearchPathForDirectoriesInDomains((type==0?NSDocumentDirectory:(type==1?NSLibraryDirectory:NSCachesDirectory)), NSUserDomainMask, YES); NSString* spath =[paths objectAtIndex:0]; if(dirname.length>0) spath = [NSString stringWithFormat:@"%@/%@/%@", spath, dirname, filename]; else spath = [NSString stringWithFormat:@"%@/%@", spath, filename]; return [[NSData alloc] initWithContentsOfFile:spath]; } @end
testCache = [[MyUrlCache alloc]initWithMemoryCapacity:1024*1024*12 diskCapacity:1024*1024*120 diskPath:@"jiayuanAssitant.db"]; [testCache initilize]; [NSURLCache setSharedURLCache:testCache];