0

I'm struggling to load cached image. On button press I'm either displaying an image if cached or downloading it then saving to cache. On the first click i get my label saying "Download From Web, and on the second click it loads from cache as I get "Loaded from cache"

However, when i restart the app i get both labels once again, like the image didn't actually cache, "Download from web" on first click and "loaded from cache" on any click thereafter.

    let imageCache = NSCache<AnyObject, AnyObject>()



    @IBAction func Button(_ sender: Any)//download charts
    {
    let imageUrl = URL(string: "https://www.vedur.is/photos/flugkort/PGDE14_EGRR_0000.png")

    if let imageFromCache = imageCache.object(forKey: imageUrl as AnyObject) as? UIImage {
        self.Image1.image = imageFromCache
        self.Image2.text = "Loaded from cache"
        return
    }

    URLSession.shared.dataTask(with: imageUrl!) { data, response, error in
        if let data = data { DispatchQueue.main.async
            {
                let imageToCache = UIImage(data: data)
                imageCache.setObject(imageToCache!, forKey: imageUrl as AnyObject)
                self.Image1.image = imageToCache
                self.Image2.text = "Downloaded From Web"
            }

        }
    }.resume()
}

2 Answers2

1

However, when i restart the app i get both labels once again, like the image didn't actually cache

That's because NSCache is a memory cache, not a disk cache. The things you add to an instance of NSCache aren't persistent across restarts. If you want to avoid fetching the same image from the network after restarting your app, you'll need to save the image to secondary storage and read it back when the app starts, or when you need the image again. NSCache will keep objects in memory while it can, and then release them when memory is scarce. So once you've downloaded the image and saved it to disk, you could keep it in a NSCache to keep it in memory so that you don't have to hit the disk a second time. That can help with performance if you've got a lot of images or other large resources that you'd like to keep on hand, but which you can also read in again if you need to.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • Well that ruins my way of storing data offline, what kind of cache do I need ? –  Apr 09 '20 at 17:34
  • 1
    You write code for it. You can read images from a file or write them to a file. – gnasher729 Apr 09 '20 at 17:37
  • 1
    There are a plenty of 3rd party options, and writing your own is also pretty straightforward. But if I were you, for the needs you've expressed, I'd start with [NSURLCache](https://developer.apple.com/documentation/foundation/nsurlcache). – Caleb Apr 09 '20 at 17:37
  • I see, I have downloaded SDWebImage which works but has limited features. If I’m downloading aprox 20 png images is there any benefit between saving to file or cache? And is there a memory limit on both? –  Apr 09 '20 at 19:45
0

If you need to use swift cache, you can try swiftlycache, which is a cache library written in swift 5. All types that comply with the code can be accessed directly, or only for memory cache and disk cache. Maybe you will like it

hlc
  • 1