Как обновить изображение в кеше при изменении изображения на сервере с помощью SDWebImage

Я использую библиотеку SDWebImage для загрузки изображений с сервера. https://github.com/rs/SDWebImage

SDWebImage не может обновить кешированное изображение, когда изображение обновляется на сервере с тем же URL-адресом.


person Shubham    schedule 18.02.2015    source источник


Ответы (6)


SDWebImage по умолчанию выполняет некоторое кэширование, поэтому было бы лучше использовать новый URL-адрес, если изображение изменится. Так, например, если у вас есть контроль над URL-адресом и вы можете изменять его каждый раз, когда изображение меняется, вы можете это сделать.

Если это не так, попробуйте использовать SDWebImageRefreshCached в поле options, чтобы учитывать заголовки управления кешем HTTP, например:

[imageView setImageWithURL:[NSURL URLWithString:@"https://graph.facebook.com/olivier.poitrey/picture"]
          placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"]
                   options:SDWebImageRefreshCached];

Подробнее см. здесь

person Edgar    schedule 18.02.2015
comment
Я уже пробовал этот код, но он не обновляет изображение. Проблема в том, что когда я обновляю изображение на сервере и возвращаюсь к предыдущему экрану, изображение остается таким же после перезагрузки представления таблицы. - person Shubham; 18.02.2015
comment
Вы должны убедиться, что сервер устанавливает правильные заголовки управления кешем HTTP. Я только что протестировал пример проекта со структурой Master->Detail и одной ячейкой с изображением из URL-адреса, переданного из Dropbox, перешел на экран сведений, изменил изображение в Dropbox, сохранив то же имя и общий URL-адрес, убедившись, что Dropbox закончилась синхронизация, снова нажал на приложение, и изображение обновилось. Взгляните на пример проекта RefreshCachedImageTest. - person Edgar; 18.02.2015
comment
Да, это рабочий префект для изображений Dropbox. Я думаю, что проблема на стороне сервера. Есть ли у вас какие-либо представления о серверной части? - person Shubham; 19.02.2015
comment
Вышеупомянутый метод работал, но устарел, теперь доступен следующий метод: [photoView setImageWithURL: [NSURL URLWithString:strPhoto] placeholderImage: [UIImage imageNamed: @imageName] options: SDWebImageRefreshCached с использованиемActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; - person Aanchal Chaurasia; 03.03.2017
comment
это все еще не работает, когда изображения меняются на URL-адресе сервера .... но URL-адрес такой же, как и раньше, библиотека не обнаруживает изменение изображения - person Pulkit Kumar Singh; 28.01.2019

Обновление: я написал целое руководство по кешу, включая проверку кеша https://kean.github.io/blog/image-caching

SDWebImage использует NSURLCache, когда вы устанавливаете опцию SDWebImageRefreshCached. Система загрузки URL-адресов Apple реализует HTTP-кеш, включая проверку кэшированных ответов. HTTP-кеширование довольно сложное, однако существует множество руководств по HTTP-кэшированию для начинающих:

По сути, серверу необходимо включать некоторые заголовки управления кешем HTTP в каждый ответ. Существует множество различных стратегий, которые можно использовать для реализации повторной валидации. Вы можете использовать Last-Modified или ETag. Таким образом, каждый раз, когда клиент отправляет запрос, он автоматически включает в ваш запрос значение Last-Modified или ETag из ранее кэшированного ответа. Если изображение не изменилось, сервер ответит кодом состояния 302 (не изменено), и NSURLConnection/NSURLSession прозрачно предоставит вам кэшированный ответ от NSURLCache. Вам не нужно загружать данные снова, но вам все равно нужно сверяться с сервером каждый раз, когда вы делаете запрос.

Вы также можете указать дату истечения срока действия с помощью управления кешем HTTP. Если используется механизм истечения срока действия, NSURLConnection/NSURLSession не будет перепроверять кэшированный ответ до тех пор, пока срок его действия не истечет.

Дополнительные сведения об управлении кешем HTTP см. по ссылкам выше. HTTP-кеш — это универсальный механизм кэширования, который следует использовать по возможности.

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

person kean    schedule 25.02.2015
comment
в другой заметке, когда я пытаюсь использовать Nuke, есть ли способ просто удалить определенное изображение из кеша и перезагрузить новое? Также способ очистить весь кеш, чтобы все изображения перезагружались с сервера? - person vishal dharankar; 18.07.2017

Вот код в swift 3 для обновления кеша каждый раз

imgCardBack.sd_setImage(with: URL(string: objUserData.back_image!), placeholderImage:UIImage(named: "cardBack"), options: .refreshCached)
person Hardik Thakkar    schedule 28.04.2017
comment
Вы использовали последнюю версию SDWebImage? - person Hardik Thakkar; 31.05.2018
comment
С какой целью вы используете этот метод? потому что в основном используется, когда мы обновляем любое изображение, и его URL-адрес такой же, но изображение является новым в то время, чтобы получить новое обновленное изображение, которое мы можем использовать вышеописанный метод. - person Hardik Thakkar; 31.05.2018
comment
Да, с той же целью я пробовал. Но все равно не работает, показывает старое изображение. - person The iCoder; 31.05.2018
comment
Является ли URL-адрес изображения созданным бэкэнд-разработчиком? или вы передаете какое-либо имя для этого? - person Hardik Thakkar; 31.05.2018
comment
Давайте продолжим обсуждение в чате. - person Hardik Thakkar; 31.05.2018
comment
Таким образом, вы можете решить эту проблему другим способом. Вы можете сказать ему/ей добавить значение метки времени в URL-адрес изображения, поэтому каждый раз, когда URL-адрес отличается и нет необходимости использовать функцию кеша, он будет автоматически обновляться. - person Hardik Thakkar; 31.05.2018

Swift 4 Просто используйте следующую функцию в библиотеке SDWebImage:

SDImageCache.shared().removeImage(forKey: (ImagePath), withCompletion: nil)

Эта функция удалит сохраненную наличность в памяти и на диске, после чего просто загрузите новое изображение, и оно будет работать отлично.

person Remon Atef    schedule 19.02.2019
comment
Обратите внимание, что ImagePath — это путь, который вы используете для загрузки изображения без заголовков URL. - person Remon Atef; 19.02.2019
comment
Как получить путь из URL? - person Lee Probert; 26.06.2019
comment
Он работает... Путь к изображению - это, по сути, URL-адрес изображения... и этот URL-адрес используется в качестве ключа для NSCache... - person Abhinav Dobhal; 02.08.2019

Перейдите к строке номер 176 в файле SDWebImageManager.m и измените эту строку

if (options & SDWebImageRefreshCached) downloaderOptions |= SDWebImageDownloaderUseNSURLCache;

код ниже.

if (options & SDWebImageRefreshCached) {
      // force progressive off if image already cached but forced refreshing
      downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;
      // remove SDWebImageDownloaderUseNSURLCache flag
      downloaderOptions &= ~SDWebImageDownloaderUseNSURLCache;
      //ignore image read from NSURLCache if image is cached but force refreshing
       downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;
}

Для меня это сработало как шарм.

person Purnendu roy    schedule 24.09.2018

Если URL-адрес не изменен, теперь SDWebImage может узнать, что изображение было изменено на сервере.

person salabaha    schedule 18.02.2015
comment
Спасибо за ответ. URL-адрес тот же, когда изображение обновляется на сервере. Проблема в том, что когда я обновляю изображение на сервере и возвращаюсь к предыдущему экрану, изображение остается таким же после перезагрузки представления таблицы. - person Shubham; 18.02.2015
comment
Да, изображение то же самое, потому что оно уже кэшировано, а URL-адрес не изменен. Таким образом, SDWebImage не может знать, что изображения были изменены на стороне сервера. Попробуйте решение Edgar. - person salabaha; 18.02.2015
comment
Да, это проблема. Но когда я перезагружаю табличное представление, оно должно обновить изображение. - person Shubham; 18.02.2015
comment
Когда вы перезагружаете кэшированные изображения TableView, они отображаются, потому что SDWebImage кэшировал ваши изображения внутри. Я имею в виду, что каждый раз, когда вы перезагружаете табличное представление, SDWebImage проверяет, есть ли кешированное изображение для определенного URL-адреса, и если да, то отображает его. Таким образом, пока URL-адрес не изменится, изображение также не изменится. - person salabaha; 18.02.2015
comment
Если у вас нет доступа к серверу и вы не можете изменить URL-адрес при изменении изображения, единственным решением, которое я вижу на данный момент, является очистка кеша SDWebImage, например, перед перезагрузкой представления таблицы. - person salabaha; 18.02.2015