Что происходит с SDWebImage Cached Images в моем приложении при изменении файла изображения на сервере?
Я использую SDWebImage
библиотека для кэширования веб-изображений в моем приложении:
https://github.com/rs/SDWebImage/blob/master/README.md
Текущее использование:
[imageView setImageWithURL:[NSURL URLWithString:profilePictureUrl] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
У меня вопрос: что произойдет, когда изображение будет кэшировано, а затем через пару дней этот файл изображения на сервере будет обновлен новым образом?
На данный момент мое приложение все еще отображает кэшированное изображение.
Я не вижу ни в одной документации по настройке тайм-аута кэша или чего-то, что распознает, что размер файла изменился.
Если у кого-то есть опыт использования этой конкретной библиотеки, то любая помощь будет принята с благодарностью.
Заранее спасибо.
10 ответов
Я посмотрел на исходный код. Обрабатывает setImageWithURL
метод как это:
- Спросите кеш памяти, если изображение есть, если да, верните изображение и не идите дальше
- Спросите кеш диска, есть ли изображение, если да, верните изображение и не идите дальше
- Попробуйте загрузить изображение, вернуть изображение в случае успеха, иначе сохранить изображение заполнителя
Не отправляется запрос, чтобы спросить удаленный сервер, есть ли новая версия, когда на диске есть что-то старое, например, использование ETag протокола HTTP.
Если копнуть немного глубже, то время кеша устанавливается в статическое значение в SDImageCache.m
static NSInteger cacheMaxCacheAge = 60*60*24*7; // 1 week
это не может быть изменено с помощью сеттера.
Так что пока изображение в кеше действительно SDWebImage
lib не будет загружать ничего нового Через неделю он загрузит ваше измененное изображение.
Ты можешь использовать options
параметр.
Swift версия:
imageView.sd_setImage(with: URL(string: URLWithString:profilePictureUrl),
placeholderImage: UIImage(named: "placeholder"),
options: .refreshCached,
completed: nil)
Версия Objective-C:
[imageView sd_setImageWithURL:[NSURL URLWithString:profilePictureUrl]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
options:SDWebImageRefreshCached
completed: nil];
Ура!
Проблема со старением SDImageCache (который теперь имеет сеттер: maxCacheAge) заключается в том, что SDWebImage никогда не делает с ним ничего проактивного. Вам нужно вызвать cleanDisk самостоятельно в какой-то момент, чтобы удалить старые данные из кэша. Примечание: SDWebImage вызывает cleanDisk, когда приложение завершает свою работу, но приложениям не гарантируется получение уведомления о завершении из ОС.
NSURL *imageUrl = nil;
NSDate *lastUpdate = [[NSUserDefaults standardUserDefaults] objectForKey:@"lastUpdate"];
NSDate *currentDate = [NSDate date];
if (lastUpdate == nil
|| ![lastUpdate isKindOfClass:[NSDate class]]
|| [currentDate timeIntervalSinceDate:lastUpdate] > 60 * 60 *24) {
[[NSUserDefaults standardUserDefaults] setObject:currentDate forKey:@"lastUpdate"];
NSString *urlString = [NSString stringWithFormat:@"http://yourdomain.com/image/image.png?%f", [currentDate timeIntervalSince1970]];
imageUrl = [NSURL URLWithString:urlString];
}
Если вы хотите изменить длительность кэша по умолчанию в Swift. Установите это в вашем AppDelegate.
Версия 3:
SDWebImageManager.sharedManager().imageCache.maxCacheAge = CACHE_TIME_IN_SECONDS
Версия 4:
SDWebImageManager.shared().imageCache?.config.maxCacheAge = CACHE_TIME_IN_SECONDS
-
Я считаю, что это влияет только на изображения, которые являются кэшами после установки этого значения. То есть, если ваше приложение кэширует изображение с истечением срока действия кэша по умолчанию, а затем изменяет его на что-то другое, ваши изображения все еще будут иметь срок действия только через неделю. Простое решение этой проблемы - просто очистить кеш.
Ниже то, что я заметил.
Если имя / путь к изображению совпадают, SDWebImage не будет загружать его снова в течение 1 недели.
Независимо от имени изображения, SDWebImage повторно загрузит изображение через 1 неделю (с момента его загрузки).
static NSInteger cacheMaxCacheAge = 60*60*24*7; // 1 week
У них есть одна база данных, где хранятся все изображения URL. Для них URL-адрес изображения похож на первичный ключ (уникальный ключ).
Таким образом, в основном, что они делают, если URL-адрес изменен и отсутствует в БД, загрузите его.
С моей точки зрения, то, что они делают, ПРАВИЛЬНО. Ex. Если вы загружаете изображение, скажем, для пользователя А, имя изображения должно быть изменено, и это является основным. Я знаю, что некоторые разработчики предпочитают, чтобы имя изображения было одинаковым (как и у userA.png всегда).
SDWebImage выполняет агрессивное кэширование по умолчанию. Но теперь они дают возможность уважать ваши заголовки управления кэшированием HTTP и получать последние изображения.
Для этого у них есть новый метод, где в настройках вы можете передать SDWebImageRefreshCached
[imageView sd_setImageWithURL:[NSURL URLWithString:@"https://graph.facebook.com/xyz/picture"]
placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"]
options:SDWebImageRefreshCached];
Вы можете найти полную информацию о методе и объяснение здесь.
Поток SDWebImage:
1) SDWebImage
кэширует изображение, полученное с сервера
2) SDWebImage
использует url-ключ для получения изображения из кеша
3) SDWebImage
проверки:
если он может получить изображение из кеша - ОК
если нет (например, URL был изменен) - не удалось получить изображение из кэша
так что на самом деле, вы получите пустой ImageView (ы) и SDWebImage
необходимо снова получить изображения с сервера
Последний Swift 3.0* и SDWebImage
SDWebImageManager.shared().imageCache?.deleteOldFiles(completionBlock: nil)
Как я прочитал в readme SDWeb в git, это может помочь:
В вашем случае вы можете использовать SDWebImageRefreshCached
флаг. Это немного ухудшит производительность, но будет учитывать заголовки элемента управления HTTP-кэшированием:
[imageView sd_setImageWithURL:[NSURL URLWithString:@"https://graph.facebook.com/olivier.poitrey/picture"]
placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"]
options:SDWebImageRefreshCached];