使用 SDWebImage 在服务器上更改图像时如何更新缓存中的图像

How to update image in cache when image changed on server with SDWebImage

我正在使用 SDWebImage 库从服务器下载图像。 https://github.com/rs/SDWebImage

当图像在服务器上更新为相同 url.

时,SDWebImage 无法更新缓存的图像

如果 URL 未更改,现在 SDWebImage 可以知道服务器上的图像已更改。

SDWebImage默认做一些缓存,所以如果图像改变了,最好使用新的URL。因此,例如,如果您可以控制 URL 并且可以在每次图像更改时更改它,您就可以这样做。

如果不是这种情况,请尝试在 options 字段中使用 SDWebImageRefreshCached 以遵守 HTTP 缓存控制 headers,如下所示:

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

查看更多here

更新:实际上我写了一个关于缓存的完整指南,包括缓存验证https://kean.github.io/blog/image-caching

当您设置 SDWebImageRefreshCached 选项时,

SDWebImage 使用 NSURLCache。 Apple 的 URL 加载系统实现了 HTTP 缓存,包括缓存的响应验证。 HTTP 缓存相当复杂,但是有很多关于 HTTP 缓存的新手指南:

基本上,服务器需要在每个响应中包含一些 HTTP 缓存控制 headers。有许多不同的策略可用于实施重新验证。您可以使用 Last-ModifiedETag。这样,每次客户端发送请求时,它都会自动在您的请求中包含先前缓存的响应中的 Last-ModifiedETag 值。如果图像没有改变,服务器将响应状态代码 302(未修改)并且 NSURLConnection/NSURLSession 将透明地为您提供来自 NSURLCache 的缓存响应。不用重新下载数据,每次请求还是要和服务器核对一下。

您还可以使用 HTTP 缓存控制指定到期日期。如果使用过期机制,NSURLConnection/NSURLSession 将不会重新验证缓存的响应,直到它没有过期。

有关 HTTP 缓存控制的详细信息,请参阅上面的链接。 HTTP 缓存是一种通用缓存机制,应尽可能使用。

我建议使用 Nuke 框架来加载图像(免责声明:由我撰写)。它默认使用 NSURLCache,同时仍然有一个内存缓存来保存解压缩的图像。

下面是swift3中的一段代码,每次刷新缓存

imgCardBack.sd_setImage(with: URL(string: objUserData.back_image!), placeholderImage:UIImage(named: "cardBack"), options: .refreshCached)

转到文件中的第 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;
}

对我来说,它就像一个魅力。

Swift 4 只需使用 SDWebImage 库中的以下函数:

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

此功能将删除内存和磁盘中保存的现金,之后只需同时上传您的新图像即可完美运行。