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

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

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

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

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

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

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

Ответ 1

Обычно проще создать запрос, подобный этому

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;
}

Ответ 2

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

- (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 credentials
        NSDictionary *credentials = [credentialsStorage credentialsForProtectionSpace:protectionSpace];
        //iterate through twitter credentials, and erase them all
        for (NSString *credentialKey in credentials)
            [credentialsStorage removeCredential:[credentials objectForKey:credentialKey] forProtectionSpace:protectionSpace];
    }
}

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

Ответ 3

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

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

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

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

Ответ 4

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

        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];

Ответ 5

Если вы используете 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 или официальной документации об этом, что я могу сказать)

Ответ 6

NSMutableURLRequest* request = [[NSMutableURLRequest alloc] url];
[request setValue:@"no-store" forHTTPHeaderField:@"Cache-Control"];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];

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

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

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