AFNetworking 2.0-принудительное кэширование


Можно ли принудительно кэшировать ответ, если он не содержит ни Expires, ни Cache-Control: max-age?

Я наткнулся на ЭТУ статью, но, к сожалению, URLSession:dataTask:willCacheResponse:completionHandler: никогда не вызывается в моем подклассе AFHTTPSessionManager.

Любая помощь ценится.

1 7

1 ответ:

Вы можете принудительно выполнить кэширование, реализовав свой собственный NSURLProtocol, который не следует стандартным правилам кэширования HTTP. Полный учебник находится здесь , который сохраняет данные с использованием основных данных, но основные шаги таковы:

  • подкласс NSURLProtocol
  • зарегистрируйте свой подкласс с помощью +registerClass:
  • верните YES в свой метод +canInitWithRequest:, если это первый раз, когда вы видели request, или NO, если это не

Теперь у вас есть два варианта:

  1. реализовать ваше собственное хранилище кэша (в этом случае следуйте инструкциям, приведенным выше)
  2. введите заголовки управления кэшем, которые вы хотите, чтобы система Загрузки URL следовала

Предполагая, что вы хотите #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];
}

Это приведет к кэшированию ответа, как если бы сервер предоставил эти заголовки.


Только для сеансов URL вам необходимо задайте конфигурацию сеанса protocolClasses. Поскольку вы используете AFNetworking, это выглядит следующим образом:

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

Есть некоторые предостережения, поэтому убедитесь, что вы прочитали protocolClasses документацию.


Несколько примечаний:

  • Если есть какой-либо способ исправить это, попросив ваш сервер отправить соответствующие заголовки, пожалуйста, сделайте это вместо этого.
  • для краткости я жестко закодировал "HTTP / 1.1", но технически вы должны вытащить это из ответ.
  • AFNetworking использует стандартную систему Загрузки URL-адресов и в основном не имеет отношения к этой проблеме.