Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the Kingfisher default cache behavior?

I am using Kingfisher library for the purpose of caching images in UICollectionView cells.

I noticed that calling kf_setImage (assuming that the name of the cell called listCell and its ImageView called imgMain) as follows:

listCell.imgMain.kf.setImage(with: URL(string: "MY IMAGE URL"),
                             placeholder: UIImage(named: "PLACEHOLDER IMAGE"))

works fine, it does caches the image and display it when cell has been re-dequeued (when scrolling up and down, I can see the image directly without re-downloading it), but when I pull to refresh the collection view (recall the API with the same exact parameters, which means that it will return the same image urls) the images have been re-downloaded! I assume that the images already have been cached.

To make it more clear, this link contains gif image that describes what am I facing.

So, why the images get downloaded once again? is it the default behavior of the caching in Kingfisher? Is there any configuration that should edited to behave as I expect?

I read the library documentation, but -unfortunately- I couldn't find and useful information related to what am I asking for.

like image 796
Ahmad F Avatar asked Mar 27 '17 14:03

Ahmad F


People also ask

What is Kingfisher in ios?

Kingfisher is a powerful, pure-Swift library for downloading and caching images from the web. It provides you a chance to use a pure-Swift way to work with remote images in your next app.

What is image caching in Swift?

Cache is a hardware or software component that stores data so future requests for that data can be served faster; the data stored in a cache might be the result of an earlier computation, or the duplicate of data stored elsewhere.


2 Answers

Kingfisher is using the whole url as the cache key by default, so you have to ensure that you have the very SAME url string for the images every time you request your API. If there is something like timestamp or version number appended to the urls, the cache will fail. (eg. http://example.com/image.png?time=123 and http://example.com/image.png?time=456 will be recognized as two different cache keys, although you could get the same image from it).

This is the only case I could draw for your operation. If this is true for you, you could create an ImageResource to specify the cache key explicitly (which should be related to your original url, but get rid of the appended things):

let r = ImageResource(downloadURL: yourUrl, cacheKey: key)
imageView.kf.setImage(with: r, placeholder: yourImage)
like image 119
onevcat Avatar answered Oct 01 '22 13:10

onevcat


According to the behaviour of Kingfisher I saw before for the loading of the cells initially is getting the images and saving to a cache.

Every time you scroll it handle it the change of image, reload, getting from the cache, etc. In your Pull to refresh you're reloading your data source, so Kingfisher would try to reload the cache again, of course, you can avoid it handling the cache manually yourself with Kingfisher or specifying in the options of the kf_setImage method.

If see the signature of the method kf_setImage:

public func kf_setImage(with resource: Resource?,
                          placeholder: Image? = nil,
                              options: KingfisherOptionsInfo? = nil,
                        progressBlock: DownloadProgressBlock? = nil,
                    completionHandler: CompletionHandler? = nil) -> RetrieveImageTask

It has the options parameter nil by default. You can specify in these parameters like the onlyFromCache and if set, Kingfisher will only try to retrieve the image from the cache, not from the network.

imageView.kf.setImage(with: url, options: [.onlyFromCache])

The another way if customising the ImageCache and ImageDownloader to your requirements.

But you need to be careful because when you do a Pull to Refresh the default behaviour should be shown first the images from the cache and update it as it comes from the network, so you need to handle it in some way like this.

I hope this help you

like image 40
Victor Sigler Avatar answered Oct 01 '22 13:10

Victor Sigler