2014-08-30 52 views
7

如果它既不包含ExpiresCache-Control: max-age,也可以強制響應緩存?AFNetworking 2.0 - 強制高速緩存

我遇到過this文章,但不幸URLSession:dataTask:willCacheResponse:completionHandler:永遠不會在我的AFHTTPSessionManager子類中被調用。

任何幫助表示讚賞。

+0

您可以使用['cachePolicy'](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSMutableURLRequest_Class/index.html#//apple_ref/occ/instp/NSMutableURLRequest/cachePolicy)屬性'NSMutableURLRequest'。 – fluidsonic 2014-10-01 01:22:57

回答

6

您可以通過實施自己的NSURLProtocol來強制緩存,該緩存不遵循標準的HTTP緩存規則。一個complete tutorial is here,其持續使用核心數據的數據,但基本步驟是:

  • 子類NSURLProtocol
  • +registerClass:
  • 返回YES+canInitWithRequest:方法註冊你的子類,如果這是你第一次」見過request,或NO如果不是

現在你有兩個選擇:

  1. 實現你自己的緩存存儲(在這種情況下,按照上面鏈接的教程)
  2. 注入你希望的網址加載系統遵循

緩存控制頭假設你想要#2,覆蓋connection:didReceiveResponse:在協議的子類來創建具有緩存控制頭的響應要效仿:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response { 
    // Create a dictionary with the headers you want 
    NSMutableDictionary *newHeaders = [response.allHeaderFields mutableCopy]; 
    newHeaders[@"Cache-Control"] = @"no-transform,public,max-age=300,s-maxage=900"; 

    // Create a new response 
    NSHTTPURLResponse *newResponse = [[NSHTTPURLResponse alloc] initWithURL:response.URL 
                   statusCode:response.statusCode 
                   HTTPVersion:@"HTTP/1.1" 
                   headerFields:newHeaders]; 


    [self.client URLProtocol:self 
      didReceiveResponse:newResponse 
      cacheStoragePolicy:NSURLCacheStorageAllowed]; 
} 

這將導致響應被緩存爲如果服務器已經提供了第ese標題。


對於URL會話只,您需要設置會話配置的protocolClasses。由於您使用的AFNetworking,看起來像:

[AFHTTPSessionManager sharedManager].session.configuration.protocolClasses = @[[MyURLProtocol class]] 

有一些注意事項,所以一定要read the protocolClasses documentation


的幾個注意事項:

  • 如果有任何方式讓您的服務器發送相應的頭文件,以解決這個問題,請你,請這樣做吧。
  • 爲了簡潔起見,我對硬編碼的「HTTP/1.1」進行了硬編碼,但從技術上講,您應該將其從響應中解脫出來。
  • AFNetworking使用標準的URL加載系統,並且與這個問題大多無關。
+0

非常感謝!剛回到城裏,明天就會深入挖掘,然後獎賞你的賞金。 – 2014-09-29 18:17:46

+0

@BenW酷,讓我知道你是否有任何問題。 – 2014-09-29 20:22:35

+0

得到了這一切設置,但由於某種原因,即使當我從canInitWithRequest返回YES時,startLoading永遠不會在我的NSURLProtocol子類上調用。這兩種方法都會在加載圖像時調用,但在向我的api加載請求時不會調用startLoading。曾見過? – 2014-09-30 21:27:11