Можно ли предотвратить NSURLRequest от кэширования данных или удалить кэшированные данные после запроса?

На iPhone я выполняю HTTP-запрос, используя NSURLRequest для фрагмента данных. Пики распределения объектов, и я назначаю данные соответственно. Когда я заканчиваю с данными, я освобождаю их соответственно - однако инструменты не показывают никаких данных, которые должны были быть освобождены!

Моя теория заключается в том, что по умолчанию кэшируются HTTP-запросы - я не хочу, чтобы мое приложение для iPhone кэшировало эти данные.

Есть ли способ очистить этот кеш после запроса или предотвратить кеширование данных?

Я попытался использовать все политики кэширования, описанные ниже:

NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
theRequest.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;

но ничто не освобождает память!

6 ответов

Решение

Обычно проще создать такой запрос

NSURLRequest *request = [NSURLRequest requestWithURL:url
      cachePolicy:NSURLRequestReloadIgnoringCacheData
      timeoutInterval:60.0];

Затем создайте соединение

NSURLConnection *conn = [NSURLConnection connectionWithRequest:request
       delegate:self];

и реализовать соединение:willCacheResponse: метод на делегате. Просто возвращение ноль должно сделать это.

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
  return nil;
}

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

- (void) eraseCredentials{
NSURLCredentialStorage *credentialsStorage = [NSURLCredentialStorage sharedCredentialStorage];
NSDictionary *allCredentials = [credentialsStorage allCredentials];

//iterate through all credentials to find the twitter host
for (NSURLProtectionSpace *protectionSpace in allCredentials)
    if ([[protectionSpace host] isEqualToString:@"twitter.com"]){
        //to get the twitter's credentials
        NSDictionary *credentials = [credentialsStorage credentialsForProtectionSpace:protectionSpace];
        //iterate through twitter's credentials, and erase them all
        for (NSString *credentialKey in credentials)
            [credentialsStorage removeCredential:[credentials objectForKey:credentialKey] forProtectionSpace:protectionSpace];
    }
}

Я надеюсь, что это работает для кого-то:)

Если вы используете NSURLConnection, взгляните на делегата:

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse

Возвращаемое значение

Фактический кешированный ответ для хранения в кеше. Делегат может вернуть cachedResponse без изменений, вернуть измененный кэшированный ответ или вернуть nil, если для соединения не должен храниться кэшированный ответ.

Если вы используете NSURLSessionдругое решение, предотвращающее запись запроса и параметров в Cache.db iOS создает в приложении Caches каталог, чтобы установить NSURLCache для конфигурации сеанса для памяти 0 размера и дискового кэша 0 размера, например

let configuration = URLSessionConfiguration.default    
configuration.urlCache = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)
let session = URLSession(configuration: configuration)

или, как указано выше, установлен на глобальном уровне кэша

URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)

Предположительно, это 0 для размера диска, который останавливает запись iOS на диск, но если у вас есть политика для reloadIgnoringLocalCacheData тогда вы, вероятно, не заинтересованы в кэшировании памяти.

Примечание. Это предотвратит Caches/Cache.db (запросы и ответы) или Caches/fsCachedData/ папка (данные ответа) создается вообще. Мы решили использовать этот подход в приложении в целях безопасности, так как не хотим, чтобы наши запросы хранились в кеше диска.

Если кто-нибудь знает, есть ли способ остановить только кэширование запросов, но сохранить кэширование данных ответов из механизма загрузки URL-адресов iOS, мне было бы интересно узнать. (по этому поводу нет API или официальной документации)

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

        int cacheSizeMemory = 0*4*1024*1024; // 0MB
        int cacheSizeDisk = 0*32*1024*1024; // 0MB
        NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"];
        [NSURLCache setSharedURLCache:sharedCache];
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] url];
[request setValue:@"no-store" forHTTPHeaderField:@"Cache-Control"];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];

Предполагая, что сервер правильно реализован, Cache-Control:no-store заголовок в запросе сгенерирует ответ сервера с тем же заголовком, вызывая тем самым NSURLCache не хранить данные ответов на диске.

Таким образом, нет необходимости в подходе дробовика отключения NSURLCache кеширование диска.

PS: Добавление заголовка должно работать для всех HTTP-фреймворков, например AFNetworking

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