最近做優化網頁請求 研究了下NSURLCache ?實現離線加載網頁數據
? ? 代碼:?KLURLCache
? ? 博客:@火柴大男人
網上找了很多資料,寫的好的是一個外國人寫的但也是2012年寫的..很多東西已經過時 代碼風格也是MRC.
國內有些人翻譯過來,自己寫成中文版,看了一下也沒有DEMO代碼. 查了其它的一些文章試了下,大多只是在講理論.都 沒有代
碼DMEO.感覺研究起來費時間. ?后來找一份實現代碼.也有相關 博客說明.代碼是MRC 有些方法也過期了..本人就是參考那份
代碼實現,并做了一些改進.
寫文章前一直找當時下載代碼的地方 和博客地址 ?希望 注明一下引用一下.以示對原作者的尊重..但由于當時沒有標記位置.現在也無法找到當時出處.所以在此謝過原作者的開源精神!!
第一步:
創建一個類繼承 NSURLCache?
@interface KLURLCache : NSURLCache
重寫這個方法,,該方法是設置 內存 與 磁盤緩存 空間大小的
- (instancetype)initWithMemoryCapacity:(NSUInteger)memoryCapacity diskCapacity:(NSUInteger)diskCapacity diskPath:(NSString *)path{
if (self = [super initWithMemoryCapacity:memoryCapacity diskCapacity:diskCapacity diskPath:path]) {
if (!path) {
_diskPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
_responseInfoDict = [NSMutableDictionary? dictionaryWithCapacity:0];
}else{
_diskPath = path;
}
}
return self;
}
第二步:
關鍵的一步
重寫 這個方法 ?每個請求都 會經過這個方法.做緩存就是攔截這個方法 只要是GET請求才能緩存的
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request{
NSLog(@"%@",request.HTTPMethod);
if ([request.HTTPMethod compare:@"GET"] != NSOrderedSame) {
return [super cachedResponseForRequest:request];
}else{
return [self KL_CacheResponseDataFromRequest:request];
}
第三步:
緩存是如果做的 之前 請求都是通過[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data,NSError *error)進行的
IOS 9.0 后網絡請求改為NSURLSession 進行管理.而不是之前的 NSURLConnection 原代碼是NSURLConnection 代碼也是MRC 這個地方自己修改了;
我們拿到 全局 NSURLSession *session = [NSURLSession sharedSession];
session 請求來的數據我們寫入磁盤.
關于那個字典是什么,我們是緩存請求數據類型時間 鍵值對的.. 到時取緩存的時侯時需要用到的
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (response && data) {
[self.responseInfoDict removeObjectForKey:fileName];
}
if (error) {
cachedResponse = nil;
}
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%f", [date timeIntervalSince1970]], @"time",response.MIMEType,@"MIMEType",response.textEncodingName,@"textEncodingName" ,nil];
[dict writeToFile:otherInfoPath atomically:YES];
[data writeToFile:filePath atomically:YES];
cachedResponse = [[NSCachedURLResponse alloc]initWithResponse:response data:data];
}];
一個GET請求 類似于 鍵值對一樣..因為一個網頁不是簡單的請求一個? www.baidu.com 這么簡單..請求這個后里面還會產生很多小請求加載數據的..每次請求都 會有一個request? 我們所做的就是 根據當前request里面的URL 做一對一的緩存.
比如打開百度時? www.baidu.com 這個URL地址已經緩存了,那么當request的URL地址是這個的時侯我們就不會向風絡再發請求.而是從本地沙盒中拿相應的數據返回給到它..但百度www.baidu.com后里面可能還www.baidu.com/1323.jpg 等等.而且每次刷新在www.baidu.com里面會有新的數據.URL請求,這個時侯可能就會出現第二次打開www.baidu.com時 些是從網絡請求的.有些是從本地加載的.如下:
2016-10-21 16:57:09.928 DEMO[1924:698294] 請求的數據是---http://www.baidu.com/
2016-10-21 16:57:09.928 DEMO[1924:698294] data from Cache
......地址是----http://m.baidu.com/static/ecom/js/wise/home/ecomAds_5f3f8bc.js
2016-10-21 16:57:09.935 DEMO[1924:698304] GET
2016-10-21 16:57:09.935 DEMO[1924:698304] 請求的數據是---http://www.baidu.com/
2016-10-21 16:57:09.936 DEMO[1924:698304] data from Cache
......地址是----http://m.baidu.com/static/search/baiduapp_icon.png
2016-10-21 16:57:09.937 DEMO[1924:698351] GET
2016-10-21 16:57:09.937 DEMO[1924:698351] 請求的數據是---http://www.baidu.com/
2016-10-21 16:57:09.938 DEMO[1924:698351] data from request
地址是------http://m.baidu.com/tc?tcreq4log=1&ssid=0&from=844b&pu=sz%401320_2001%2Cta%40iphone_1_9.3_3_601&qid=15764434222633284224-2&ct=21&cst=1&ref=index_iphone&lid=15764434222633284224-2&w=0_0_&sid=110316_104496_100186_102628_104381_100100_108470_110005_107800_110394_109974_110420_110498_110011_110298_110251_109588_108013_107320_110357_110031_110270_110400&sOS=1&banner=wiseindex&r=1477040229894
2016-10-21 16:57:09.939 DEMO[1924:698351] GET