2016-08-10 2 views
1

Привет Я пишу IOS api для извлечения данных с сервера с использованием AFNetworking 3.x. Мой сервер не поддерживает кеширование. Это этот сервер заголовкаРеализация пользовательского кеша для AFNetworking 3.x

Connection →Keep-Alive 
Content-Length →4603 
Content-Type →text/html; charset=UTF-8 
Date →Wed, 10 Aug 2016 04:03:56 GMT 
Keep-Alive →timeout=5, max=100 
Server →Apache/2.4.18 (Unix) OpenSSL/1.0.1e-fips PHP/5.4.45 
X-Powered-By →PHP/5.4.45 

Я хочу построить пользовательский интерфейс API, чтобы включить кэш (например, запрос и ответ должен быть кэш 10 секунд, так что если пользователь делает тот же запрос, используется кэш данных. Если кэш истек приложение будет затем повторно загрузить снова)

Моей AFNetworking Синглтона

#pragma mark - Shared singleton instance 

+ (ApiClient *)sharedInstance { 
    static ApiClient *sharedInstance = nil; 
    static dispatch_once_t oncePredicate; 
    dispatch_once(&oncePredicate, ^{ 
     NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; 
     sharedInstance = [[self alloc] initWithBaseURL:[NSURL URLWithString:SINGPOST_BASE_URL] sessionConfiguration:sessionConfiguration]; 

    return sharedInstance; 
} 

- (id)initWithBaseURL:(NSURL *)url 
{ 
    if ((self = [super initWithBaseURL:url])) { 
     self.requestSerializer = [AFHTTPRequestSerializer serializer]; 
    } 
    return self; 
} 

запрос Моего JSON

- (void)sendJSONRequest:(NSMutableURLRequest *)request 
       success:(void (^)(NSURLResponse *response, id responseObject))success 
       failure:(void (^)(NSError *error))failure { 

    self.responseSerializer.acceptableContentTypes = [AFHTTPResponseSerializer serializer].acceptableContentTypes; 
    self.requestSerializer.timeoutInterval = 5; 
    self.requestSerializer.cachePolicy = NSURLRequestReturnCacheDataElseLoad; 

     [self setDataTaskWillCacheResponseBlock:^NSCachedURLResponse * _Nonnull(NSURLSession * _Nonnull session, NSURLSessionDataTask * _Nonnull dataTask, NSCachedURLResponse * _Nonnull proposedResponse) { 
      return [[NSCachedURLResponse alloc] initWithResponse:proposedResponse.response 
                  data:proposedResponse.data 
                 userInfo:proposedResponse.userInfo 
                storagePolicy:NSURLCacheStorageAllowed]; 
     }]; 

    NSURLSessionDataTask *dataTask = [ApiClient.sharedInstance dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { 
     if (error) { 
      NSLog(@"Error URL: %@",request.URL.absoluteString); 
      NSLog(@"Error: %@", error); 
      failure(error); 
     } else { 
      NSDictionary *jsonDict = (NSDictionary *) responseObject; 
      success(response,jsonDict); 
      NSLog(@"Success URL: %@",request.URL.absoluteString); 
      NSLog(@"Success %@",jsonDict); 
     } 
    }]; 
    [dataTask resume]; 

} 

Как изменить следующий код, чтобы включить запрос кэширования и ответ (я хочу, чтобы ответ сохранялся как 10 секунд) (Или 1 день, если нет подключения к Интернету). Любая помощь очень ценится. Благодаря!

[self setDataTaskWillCacheResponseBlock:^NSCachedURLResponse * _Nonnull(NSURLSession * _Nonnull session, NSURLSessionDataTask * _Nonnull dataTask, NSCachedURLResponse * _Nonnull proposedResponse) { 
      return [[NSCachedURLResponse alloc] initWithResponse:proposedResponse.response 
                  data:proposedResponse.data 
                 userInfo:proposedResponse.userInfo 
                storagePolicy:NSURLCacheStorageAllowed]; 
     }]; 
+0

У кого-нибудь есть идеал? –

ответ

2

Вместо

  return [[NSCachedURLResponse alloc] initWithResponse:proposedResponse.response 

сделать

  NSMutableDictionary *dictionary = [proposedResponse.response.allHeaderFields mutableCopy]; 
      dictionary[@"Cache-Control" = ... 
      NSHTTPURLResponse *modifiedResponse = 
       [[NSHTTPURLResponse alloc initWithURL:proposedResponse.response.URL 
             statusCode:proposedResponse.response.statusCode 
             HTTPVersion:@"HTTP/1.1" 
             headerFields:modifiedHeaders]; 

      [modifiedResponse 
      return [[NSCachedURLResponse alloc] initWithResponse:modifiedResponse 

Обратите внимание, что это не возможно, чтобы получить версию HTTP от исходного запроса. Я почти уверен, что подал ошибку. Я также уверен, что это ни на что не влияет, и я не думаю, что он даже хранится в базовом объекте, поэтому, вероятно, это не имеет значения.

+0

привет спасибо за помощь. Идеальным является захват заголовка ответа. Добавить поле для @ "Cache-control"? является правильным способом для ex: dictionary [@ "Cache-Control" = @ "max-age = 120, public". мы можем передать nil для HTTPVersion. Работает ли он на HTTPS? –

+0

Да к первому вопросу; вы просто устанавливаете строку как значение для этого поля заголовка. Я не знаю о передаче nil для версии HTTP. И, насколько я знаю, HTTPS не влияет на кэширование вообще. – dgatwood

+0

Спасибо за разъяснение, это будет реализовано. Как установить кеш диска и емкость кэша памяти. Значение по умолчанию. Достаточно ли этого для обычного веб-трафика (JSON, Image ...)? –