swiftxcodecachingdownloadnscache

NSCache, Image Cache, not caching (Xcode 11, Swift 5)


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

Solution

  • 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.