AFNetworking 2.0-принудительное кэширование
Можно ли принудительно кэшировать ответ, если он не содержит ни Expires
, ни Cache-Control: max-age
?
Я наткнулся на ЭТУ статью, но, к сожалению, URLSession:dataTask:willCacheResponse:completionHandler:
никогда не вызывается в моем подклассе AFHTTPSessionManager
.
Любая помощь ценится.
1 ответ:
Вы можете принудительно выполнить кэширование, реализовав свой собственный
NSURLProtocol
, который не следует стандартным правилам кэширования HTTP. Полный учебник находится здесь , который сохраняет данные с использованием основных данных, но основные шаги таковы:
- подкласс
NSURLProtocol
- зарегистрируйте свой подкласс с помощью
+registerClass:
- верните
YES
в свой метод+canInitWithRequest:
, если это первый раз, когда вы виделиrequest
, илиNO
, если это неТеперь у вас есть два варианта:
- реализовать ваше собственное хранилище кэша (в этом случае следуйте инструкциям, приведенным выше)
- введите заголовки управления кэшем, которые вы хотите, чтобы система Загрузки 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-адресов и в основном не имеет отношения к этой проблеме.