2014-08-30 17 views
7

Có thể buộc bộ nhớ đệm phản hồi nếu nó không chứa Expires hoặc Cache-Control: max-age?AFNetworking 2.0 - Buộc bộ nhớ đệm

Tôi đã xem qua this bài viết, nhưng tiếc là URLSession:dataTask:willCacheResponse:completionHandler: không bao giờ được gọi trong lớp con AFHTTPSessionManager của tôi.

Bất kỳ trợ giúp nào được đánh giá cao.

+0

Bạn có thể sử dụng ['cachePolicy'] (https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSMutableURLRequest_Class/index.html#//apple_ref/occ/instp/NSMutableURLRequest/cachePolicy) thuộc tính của 'NSMutableURLRequest'. – fluidsonic

Trả lời

6

Bạn có thể buộc bộ nhớ đệm bằng cách triển khai NSURLProtocol của riêng mình mà không tuân thủ các quy tắc bộ nhớ cache HTTP chuẩn. Một complete tutorial is here, mà vẫn tồn tại dữ liệu sử dụng Core Data, nhưng các bước cơ bản là:

  • Subclass NSURLProtocol
  • đăng ký lớp con của bạn với +registerClass:
  • Return YES trong phương pháp +canInitWithRequest: của bạn nếu đây là lần đầu tiên bạn' đã nhìn thấy request, hoặc NO nếu nó không phải là

Bây giờ bạn có hai lựa chọn:

  1. Thực hiện lưu trữ bộ nhớ cache của riêng bạn (trong trường hợp này, hãy làm theo các hướng dẫn liên kết ở trên)
  2. Tiêm các tiêu đề kiểm soát bộ nhớ cache mà bạn muốn hệ thống URL tải theo

Giả sử bạn muốn # 2, ghi đè connection:didReceiveResponse: trong phân lớp giao thức của bạn để tạo ra một phản ứng mà có tiêu đề kiểm soát bộ nhớ cache bạn muốn thi đua:

- (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]; 
} 

điều này sẽ gây ra phản ứng để được lưu trữ như nếu máy chủ đã cung cấp thứ ese tiêu đề.


Đối với phiên URL chỉ, bạn cần phải thiết lập cấu hình phiên của protocolClasses. Vì bạn đang sử dụng AFNetworking, trông giống như:

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

Có một số cảnh báo, vì vậy hãy đảm bảo bạn read the protocolClasses documentation.


Một vài lưu ý:

  • Nếu có cách nào để khắc phục điều này bằng cách có máy chủ của bạn gửi các tiêu đề phù hợp, xin vui lòng, xin vui lòng làm điều đó để thay thế.
  • Vì lợi ích ngắn gọn, tôi đã mã hóa cứng "HTTP/1.1", nhưng về mặt kỹ thuật, bạn nên rút ra khỏi phản hồi.
  • AFNetworking sử dụng Hệ thống tải URL tiêu chuẩn và hầu như không liên quan đến vấn đề này.
+0

cảm ơn rất nhiều!vừa trở về thị trấn, sẽ đào sâu vào ngày mai này và sau đó trao cho bạn tiền thưởng. –

+0

@BenW Tuyệt vời, hãy cho tôi biết nếu bạn có bất kỳ câu hỏi nào. –

+0

đã thiết lập tất cả, nhưng vì một số lý do startLoading không bao giờ được gọi trên lớp con NSURLProtocol của tôi ngay cả khi tôi trả về YES từ canInitWithRequest. cả hai phương thức sẽ được gọi khi tải hình ảnh, nhưng startLoading không được gọi khi tải yêu cầu đến api của tôi. bao giờ thấy điều đó? –