Можно ли запретить NSURLRequest кэшировать данные или удалить кэшированные данные после запроса?
-
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