Можно ли предотвратить 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