Nil while caching images

I've been able to solve the issue of caching images to improve scroll performance in my app. However nil is found when it tries to add it to cache. Also how can I add a placeholder image for images that failed to load or aren't available ? https://github.com/lexypaul13/Image-Search

extension UIImageView {
    
        func downloadImage(from imgURL: String) -> URLSessionDataTask? {
            guard let url = URL(string: imgURL) else { return nil }
    
            // set initial image to nil so it doesn't use the image from a reused cell
            image = nil
    
            // check if the image is already in the cache
            if let imageToCache = imageCache.object(forKey: imgURL as NSString) {
                self.image = imageToCache
                return nil
            }
    
            // download the image asynchronously
            let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
                if let err = error {
                    print(err)
                    return
                }
    
                DispatchQueue.main.async {
                    // create UIImage
                    let imageToCache = UIImage(data: data!)
                    // add image to cache
                    imageCache.setObject(imageToCache!, forKey: imgURL as NSString)
                    self.image = imageToCache
                }
            }
            task.resume()
            return task
    }
}
                    let imageToCache = UIImage(data: data!)

Does it crash here ?

If so, that means that data is not yet loaded when you try to access.

Just to confirm, try this:

                DispatchQueue.main.async {
                    sleep(3) // Let's wait before accessing data
                    // create UIImage
                    let imageToCache = UIImage(data: data!)

You should also make code more robust with

if let data = data, let imageToCache = UIImage(data: data) {
                    // add image to cache
                    imageCache.setObject(imageToCache, forKey: imgURL as NSString)
                    self.image = imageToCache
}

To correct it, you have several options:

  • use semaphores
  • use await/async which is made for this. But that requires some code refactoring
Nil while caching images
 
 
Q