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

StackOverflow https://stackoverflow.com/questions/405151

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

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

Это было полезно?

Решение

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top