iOS網路——NSURLCache設定網路請求緩衝,iosnsurlcache

來源:互聯網
上載者:User

iOS網路——NSURLCache設定網路請求緩衝,iosnsurlcache

今天在看HTTP協議,看到了response頭中的cache-control,於是就深入的研究了一下。發現了iOS中一個一直被我忽略的類——NSURLCache類。

 

NSURLCache

NSURLCache用於緩衝網路請求,也就是NSURLRequest,然後根據我們設定的NSURLCache策略進行相應的緩衝。

首先介紹一下各種策略

策略 意義

UseProtocolCachePolicy

 預設行為
 ReloadIgnoringLocalCacheData  不使用緩衝
 ReloadIgnoringLocalAndRemoteCacheData*  我是認真地,不使用任何緩衝
 ReturnCacheDataElseLoad  使用緩衝(不管它是否到期),如果緩衝中沒有,那從網路載入吧
 ReturnCacheDataDontLoad  離線模式:使用緩衝(不管它是否到期),但是從網路載入
 ReloadRevalidatingCacheData* 在使用前去伺服器驗證 

其中ReloadIgnoringLocalAndRemoteCacheData和ReloadRevalidatingCacheData兩種是沒有實現的,可以不看。

在建立對request使用cache的時候會讓我們選擇以上的某種策略進行,也就是

+ (instancetype)requestWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval;

該方法讓我們設定策略和時間,然後request會根據策略和時間來進行相應的調度。

 

感受NSURLCache

這裡使用預設的緩衝策略ReturnCacheDataElseLoad緩衝策略,

首先需要建立NSURLCache類

NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:0 diskPath:nil];[NSURLCache setSharedURLCache:URLCache];

1.這裡可以看到,建立參數我們制定了 4 * 1024 * 1024的記憶體(4MB) ,沒有使用磁碟空間。

2.NSURLCache使用[NSURLCache sharedURLCache]建立預設的的緩衝行為,預設為 4(MB) 記憶體和 20(MB)磁碟空間,這裡我們使用自訂的,所以要setSharedCache。

然後建立request和connection進行請求

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://172.16.25.44/test1.php"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:3];connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];[connection start];

實現NSURLConnectionDelegate協議

-(void)connectionDidFinishLoading:(NSURLConnection *)connection{    NSLog(@"finish");}

然後運行開一下請求,這裡用的工具是Charles

可以看到只有一次請求,再看控制台輸出

2015-08-04 09:29:55.297 requestCache[19405:6375355] finish2015-08-04 09:29:55.301 requestCache[19405:6375355] finish2015-08-04 09:29:55.310 requestCache[19405:6375355] finish2015-08-04 09:29:55.451 requestCache[19405:6375355] finish2015-08-04 09:29:55.618 requestCache[19405:6375355] finish2015-08-04 09:29:55.784 requestCache[19405:6375355] finish2015-08-04 09:29:55.984 requestCache[19405:6375355] finish2015-08-04 09:29:56.120 requestCache[19405:6375355] finish

所以說多次的請求只會進行一次請求,因為在記憶體中NSURLCache為我們緩衝了一份response,一旦有同樣請求就會使用緩衝。

 

緩衝持久化

緩衝如果設定本地磁碟就會為我們自動進行持久化,修改NSURLCache建立代碼

    NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];    [NSURLCache setSharedURLCache:URLCache];

設定了20MB的本地磁碟,然後運行程式,進行請求發現還是請求一次沒有變化。但是在次運行程式進行請求就會發現,一次遠程請求也不會進行了!

開啟沙箱,發現在 Library/Caches/bundleId+項目名/下面有三個檔案

這不就是sqlite麼!原來NSURLCache幫我們用sqlite將請求存入了資料庫,然後當有相同請求時就會調用緩衝!

可以想到webView如果載入一個靜態頁面不用只用請求一次,並且在效果要更新的時候遠程請求會有多爽!

 

預設策略

預設策略是 UseProtocolCachePolicy 從字面上來看是說,使用協議緩衝策略,但是什麼是協議緩衝策略呢?

在HTTP協議的response頭中,有一個欄位是cache-control,由伺服器來告訴用戶端如何使用緩衝。

下面是一個response頭

 

可以看到cache-control指定的行為是public,max-age=5

這裡先介紹一下各種指令

對應上表,可以看出了剛才回應標頭是要求緩衝所有內容,緩衝5秒失效,5秒後還要請求遠程伺服器。

對應PHP就是header("Cache-Control:public,max-age=5");

 

偽造響應

如果我們想讓一些請求,有特定的響應,我們可以自己來製作響應

    NSLog(@"%@",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]);            NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://172.16.25.44/test1.php"] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:3];    NSURLCache * cache = [NSURLCache sharedURLCache];        NSData *contentData = [@"123" dataUsingEncoding:NSUTF8StringEncoding];        NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[NSURL URLWithString:@"http://172.16.25.44/test1.php"] MIMEType:@"text/html" expectedContentLength:1000 textEncodingName:@"UTF-8"];    NSCachedURLResponse *cacheRespone = [[NSCachedURLResponse alloc] initWithResponse:response data:contentData];        [cache storeCachedResponse:cacheRespone forRequest:request];        connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];    [connection start];

如上代碼,建立了一個針對@"http://172.16.25.44/test1.php"請求的響應,並且讓 cache 對該響應進行了儲存。

實現

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{    NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];    NSLog(@"%@",dataString);}

輸出結果如下

2015-08-04 09:48:58.825 requestCache[19503:6441561] 1232015-08-04 09:48:58.826 requestCache[19503:6441561] finish2015-08-04 09:48:58.983 requestCache[19503:6441561] 1232015-08-04 09:48:58.984 requestCache[19503:6441561] finish2015-08-04 09:48:59.167 requestCache[19503:6441561] 1232015-08-04 09:48:59.167 requestCache[19503:6441561] finish2015-08-04 09:48:59.334 requestCache[19503:6441561] 1232015-08-04 09:48:59.335 requestCache[19503:6441561] finish

可以看到輸出的是我們自訂的123,而不是伺服器返回的1。

 

修改響應內容

修改響應內容需要我們實現NSURLConnectionDataDelegate 協議並實現

-(NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse{    NSMutableData *mutableData = [[cachedResponse data] mutableCopy];        //添加資料        NSCachedURLResponse *response = [[NSCachedURLResponse alloc] initWithResponse:cachedResponse.response data:mutableData];    return response;}

應為 NSCachedURLResponse 的屬性都是readonly的,所以我們想要新增內容就要建立一個可變副本增減內容。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.