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()
}
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.