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-адресов и в основном не имеет отношения к этой проблеме.