У меня есть тестовое приложение, и он успешно загружает контент из сети, даже если пользователь переключает приложения во время загрузки. Отлично, теперь у меня есть фоновые загрузки на месте. Теперь я хочу добавить кеширование. Нет смысла скачивать изображения более одного раза, b/c дизайна системы, учитывая URL-адрес изображения. Я могу сказать, что контент за этим URL-адресом никогда не изменится. Итак, теперь я хочу кэшировать результаты моей загрузки, используя ядро, встроенное в кеш-память/на диске, о котором я так много читал (в отличие от того, что я сохранил файл вручную в NSCachesDirectory, а затем проверил там, прежде чем создавать новые запрос, ick). В попытке получить кеширование, работающее над этим рабочим кодом, я добавил следующий код:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// Set app-wide shared cache (first number is megabyte value)
[NSURLCache setSharedURLCache:[[NSURLCache alloc] initWithMemoryCapacity:60 * 1024 * 1024
diskCapacity:200 * 1024 * 1024
diskPath:nil]];
return YES;
}
Когда я создаю свой сеанс, я добавил две новые строки (URLCache и requestCachePolicy).
// Helper method to get a single session object
- (NSURLSession *)backgroundSession
{
static NSURLSession *session = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.example.apple-samplecode.SimpleBackgroundTransfer.BackgroundSession"];
configuration.URLCache = [NSURLCache sharedURLCache]; // NEW LINE ON TOP OF OTHERWISE WORKING CODE
configuration.requestCachePolicy = NSURLRequestReturnCacheDataElseLoad; // NEW LINE ON TOP OF OTHERWISE WORKING CODE
session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
});
return session;
}
Затем, чтобы быть слишком избыточным в попытке увидеть успех кеширования, я переключил свою строку NSURLRequest из
// NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL]; // Old line, I've replaced this with...
NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:2*60]; // New line
Теперь, когда я иду, чтобы загрузить элемент в 2-й раз, опыт является exaccty, как первый! Занимает много времени, чтобы загружать и показывать прогресс. Анимированная анимация медленная и стабильная, как оригинальная загрузка. Я хочу, чтобы данные в кеше немедленно! Что мне не хватает???
---------------------------- UPDATE ------------------ ----------
Хорошо, спасибо Thorsten ответ, я добавил следующие две строки кода в мой метод делегата didFinishDownloadingToURL
:
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)downloadURL {
// Added these lines...
NSLog(@"DiskCache: %@ of %@", @([[NSURLCache sharedURLCache] currentDiskUsage]), @([[NSURLCache sharedURLCache] diskCapacity]));
NSLog(@"MemoryCache: %@ of %@", @([[NSURLCache sharedURLCache] currentMemoryUsage]), @([[NSURLCache sharedURLCache] memoryCapacity]));
/*
OUTPUTS:
DiskCache: 4096 of 209715200
MemoryCache: 0 of 62914560
*/
}
Это здорово. Он подтверждает, что кеш растет. Я предполагаю, что, поскольку я использую downloadTask (загрузка в файл в отличие от памяти), то почему DiskCache растет, а не кеш памяти? Я решил, что все будет идти в кеш-память до тех пор, пока не будет переполнено, а затем будет использован кеш диска, и, возможно, кэш памяти был записан на диск, прежде чем ОС убьет приложение в фоновом режиме, чтобы освободить память. Я не понимаю, как работает кеш Apple?
Это шаг вперед, но второй раз я загружаю файл, который занимает столько же времени, сколько и первый раз (может быть, 10 секунд или около того), и следующий метод снова выполняется:
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
// This shouldn't execute the second time around should it? Even if this is supposed to get executed a second time around then shouldn't it be lightning fast? It not.
// On all subsequent requests, it slowly iterates through the downloading of the content just as slow as the first time. No caching is apparent. What am I missing?
}
Что вы делаете над моими изменениями выше? Почему я не вижу, чтобы файл возвращался очень быстро при последующих запросах?
Как я могу подтвердить, будет ли файл подан из кеша во втором запросе?