NSURLCache кэшировал ответ по запросу нет данных

Почему responseCache равен нулю? я запустил бы этот пост и действительно получил responseObject из кэша. Как я могу получить responseCache?

manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];

manager.requestSerializer.cachePolicy=NSURLRequestReturnCacheDataElseLoad;

[manager POST:URL parameters:paramdic progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

    NSData * data=[NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:nil];

    NSURLCache * cache=[NSURLCache sharedURLCache];

    NSCachedURLResponse * responseCache=[cache cachedResponseForRequest:task.originalRequest];

    NSCachedURLResponse * response=[[NSCachedURLResponse alloc]initWithResponse:task.response data:data userInfo:nil storagePolicy:NSURLCacheStorageAllowed];


    [cache storeCachedResponse:response forRequest:task.originalRequest];




} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"%@",error);
}];

1 ответ

Решение

Есть три причины, по которым это nil в таком случае:

  • POST-запросы не кэшируются каким-либо сетевым кодом iOS/OS X, потому что они не гарантированно являются идемпотентными (то есть они могут иметь побочные эффекты, такие как хранение данных на сервере). Единственный способ, которым POST-запрос когда-либо хранится в NSURLCache если вы явно добавите его.
  • POST-запросы не кэшируются, потому что NSURLCache использует URL в качестве ключа поиска. Поскольку URL не включает (не может) включать тело POST, любые операции POST с тем же URL будут возвращены для другого запроса POST, что почти наверняка не то, что вы хотели бы. Поэтому, если вы все же добавите его, вам придется добавить некоторую настраиваемую перезапись URL-адреса по пути в кэш и настраиваемый код поиска, чтобы сделать URL-адреса достаточно уникальными на основе определенных полей тела POST или чего-либо еще.
  • Кэш сильно асинхронный, поэтому кэшированные данные не обязательно будут доступны, когда выполняется обработчик завершения запроса, даже если это был запрос GET.

Это не обязательно полный набор причин.:-)

Кеш предназначен для уменьшения сетевого трафика. Вы не должны вообще консультироваться с этим самостоятельно. Нормальный путь поиска, используемый NSURLSession и др. выполняет проверки для определенных политик кэширования протокола (например, истечения срока действия ответа), которые не будут выполняться простым запросом кэш-памяти, есть ли у него ответ для определенного ключа.

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

Другие вопросы по тегам