Я разрабатываю приложение, которое в значительной степени опирается на AFNetworking для загрузки данных из частного API в модели Mantle. Мой клиент API - это один подкласс класса AFHTTPSessionManager
.Блок set by setDataTaskWillCacheResponseBlock на AFHTTPSessionManager никогда не называется
Я пытаюсь реализовать базовый автономный режим, используя NSURLCache
. Подход заключается в изменении политики кэширования запроса на dataTaskWithRequest:request:completionHandler
до NSURLRequestReturnCacheDataDontLoad
, если AFNetworkReachabilityManager
говорит, что сеть недоступна.
Хотя я могу проверить, что это фактически работает с использованием контрольных точек во время тестов, сами запросы не кэшируются. Я проверил это, загрузив контейнер приложения из Xcode и проверив файл sqlite Cache.db, который был пуст. Я также проверил, что я смотрю на правильный кеш, вручную создавая манекен NSCachedURLResponse
и принудительно сохраняя его в кеше с помощью storeCachedResponse:forRequest
. Затем фиктивный ответ появился в файле sqlite Cache.db.
Итак, я думаю, что я сузил проблему, чтобы мои «обычные» ответы не кэшировались. Я также могу изменить заголовки, отправленные API-интерфейсом сервера. То, что я намереваюсь сделать здесь, задает заголовок Cache-Control: private
ответов API (чтобы не делать других клиентов, которые используют эти ответы кэша API, они не должны) и изменить этот заголовок кэша в блоке setDataTaskWillCacheResponseBlock
, но этот блок никогда не стреляет.
Я понимаю, что система URL может решить, когда звонить URLSession:dataTask:willCacheResponse:completionHandler
, который вызывает блок на основе некоторых недокументированных правил, в основном наличие заголовка Cache-Control
и отношение размера ответа/размера кеша. Но мой ответ является 145-байт в формате JSON, а заголовок Cache-Control
установлен (я проверил как через curl -v
и осматривая параметр success
блока моей просьбе task
.
Я также попытался более агрессивный заголовок кэша, Cache-Control: public, max-age=2592000
, чтобы увидеть, если это кэширует ответ или, по меньшей мере, вызывает блок, но поведение было точно так же. Я также проверил myAFHTTPSessionManagerSubclass.session.delegate
свойство, которое действительно указывал на myAFHTTPSessionManagerSubclass
, как и ожидалось.
Я также попытался перекрывая URLSession:dataTask:willCacheResponse:completionHandler
непосредственно в мой подкласс, но он все еще не был вызван. Установка точки останова на этом же методе делегата на AFURLSessionManager.m
в th e Pods
также не работает, выполнение никогда не останавливается на контрольной точке.
Я использую версию 2.5.4 AFNetworking, согласно моему файлу Podfile.lock
.
Итак, как сделать кеш ответов (желательно без установки агрессивных политик кэширования в ответ), поэтому я могу реализовать быстрый автономный режим в своем приложении?
EDIT: Я также попытался создать NSURLSession
, чтобы узнать, будет ли это работать. Итак, я создал простой сервер Node.js, что только отвечает что-то простое и устанавливает заголовок кэша:
$ curl -v http://192.168.1.107:1337/
* Hostname was NOT found in DNS cache
* Trying 192.168.1.107...
* Connected to 192.168.1.107 (192.168.1.107) port 1337 (#0)
> GET/HTTP/1.1
> User-Agent: curl/7.37.1
> Host: 192.168.1.107:1337
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
< Cache-Control: public
< Date: Thu, 11 Jun 2015 14:38:14 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
<
Hello World
А затем создал простой контроллер представления для теста:
- (void)viewDidLoad {
[super viewDidLoad];
// Prime the cache
[NSURLCache setSharedURLCache:[[NSURLCache alloc] initWithMemoryCapacity:2*1024 diskCapacity:10*1024*1024 diskPath:@"mytestcache"]];
// The sleep is to be absolutely sure the cache did initialise
sleep(2);
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
[[session dataTaskWithURL:[NSURL URLWithString:@"http://192.168.1.107:1337"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"Got response: %@", [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
}] resume];
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask willCacheResponse:(NSCachedURLResponse *)proposedResponse completionHandler:(void (^)(NSCachedURLResponse *))completionHandler {
completionHandler(proposedResponse);
}
Отклик правильно напечатанной , но willCacheResponse
никогда не вызывается (я установил точку останова).Я попытался снова проверить контейнер, и был создан каталог mytestcache
, но он был пуст. Я также пробовал Cache-Control: max-age=86400
, к тому же результату.
(кросс-размещены на AFNetworking вопросов по адресу: https://github.com/AFNetworking/AFNetworking/issues/2780)