10

I am using Kingfisher library for downloading and caching images. I am facing some issues in the implementation:

  1. Are the images cached in both memory and disk?

  2. Is there any provision to cache images only on disk?

I have already read multiple posts regarding this, but couldn't find any solution.

halfer
  • 18,701
  • 13
  • 79
  • 158
PGDev
  • 20,976
  • 5
  • 29
  • 68

3 Answers3

18

Yes, Kingfisher caches images both in memory and on disk.

By default, the amount of RAM that will be used is not even limited, you have to set the value yourself:

ImageCache.default.maxMemoryCost = 1024 * 1024 * yourValue

where 1024 * 1024 * yourValue is the global cost in megapixels (I know this is weird, but it's not megabytes, it's megapixels, because images can have different bit depth, etc).

For example, in my tests, the maximum RAM used with a value of 1024 * 1024 * 500 fluctuates between 120MB and 300MB.

Incidentally, this is also how you tell Kingfisher to never use the RAM and only cache to disk:

ImageCache.default.maxMemoryCost = 1

This will force Kingfisher to only use the disk cache.


How to debug

The first thing is to check that you're setting the max value on the right cache. Maybe you did create a custom cache? My example is setting the value for the default cache, the one used if no other is defined.

You may also want to manually clear the memory cache and compare the RAM occupation before and after:

ImageCache.default.clearMemoryCache()

If you think that some big image is in the memory cache when it shouldn't be, you can verify with isImageCached:

if let result = ImageCache.default.isImageCached(forKey: imageLink) {
    print(result.cached)
    print(result.cacheType)
}
Eric Aya
  • 68,765
  • 33
  • 165
  • 232
  • How can we check the whether the images are still stored in the memory? I have set the maxMemoryCost = 0, but still the memory is not getting released. – PGDev Jun 05 '17 at 06:45
  • So late in the game, but it's a sort of convention (unintuitively) that 0 = unlimited. API written in Swift should utilize enums with associated values for these purposes. – Ahmed Khalaf Nov 21 '20 at 10:41
  • This is not true. By default, the totalCostLimit of memory cache is 25% of your total memory in the device, and there is no limit on image count. https://github.com/onevcat/Kingfisher/wiki/Cheat-Sheet#set-limit-for-cache – gafos Jan 27 '21 at 23:50
  • @gafos Maybe it changed after I posted the answer? I don't remember, it was a long time ago. Please feel free to edit my answer with the correct information. Thanks. – Eric Aya Jan 28 '21 at 12:03
  • @EricAya The suggested edit queue is full... – gafos Jan 29 '21 at 19:55
7

If anyone looking for answer for downloading images explicitly and caching the same without using imageView the sample code is:

ImageDownloader.default.downloadImage(with: imgUrl, retrieveImageTask: nil, options: [], progressBlock: nil) { (image, error, url, data) in
                    print("Downloaded Image: \(url)")
                    //cache image:
                    if let image =  image, let url = url {
                        ImageCache.default.store(image, forKey: url.absoluteString)
                    }
                }

reference: https://github.com/onevcat/Kingfisher/wiki/Cheat-Sheet

Van
  • 1,033
  • 9
  • 17
4

Swift 5.3, Xcode 12

https://stackoverflow.com/a/44354411/10579134 , the latest version of the following

ImageCache.default.memoryStorage.config.totalCostLimit = 1 //1 in bytes
Kedar Sukerkar
  • 833
  • 8
  • 17