caching images in collectionViewCell in Swift?

自闭症网瘾萝莉.ら 提交于 2019-12-04 11:22:28
Illya Krit

Here is an example for your collection view cell:

import UIKit

let imageCache = NSCache<AnyObject, AnyObject>.sharedInstance

class myCell: UICollectionViewCell {

    @IBOutlet public weak var myImageView: UIImageView?

    private var imageUrlString: String?

    private var downloadTask: URLSessionDownloadTask?
    public var imageURL: URL? {
        didSet {
            self.downloadItemImageForSearchResult(imageURL: imageURL)
        }
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        // Initialization code
    }

    public func downloadItemImageForSearchResult(imageURL: URL?) {

        if let urlOfImage = imageURL {
            if let cachedImage = imageCache.object(forKey: urlOfImage.absoluteString as NSString){
            self.myImageView!.image = cachedImage as? UIImage
        } else {
            let session = URLSession.shared
            self.downloadTask = session.downloadTask(
                with: urlOfImage as URL, completionHandler: { [weak self] url, response, error in
                    if error == nil, let url = url, let data = NSData(contentsOf: url), let image = UIImage(data: data as Data) {

                        DispatchQueue.main.async() {

                            let imageToCache = image

                            if let strongSelf = self, let imageView = strongSelf.myImageView {

                                imageView.image = imageToCache

                                imageCache.setObject(imageToCache, forKey: urlOfImage.absoluteString as NSString , cost: 1)
                            }
                        }
                    } else {
                        //print("ERROR \(error?.localizedDescription)")
                    }
            })
            self.downloadTask!.resume()
        }
      }
    }

    override public func prepareForReuse() {
      self.downloadTask?.cancel()
      myImageView?.image = UIImage(named: "ImagePlaceholder")
    }

    deinit {
      self.downloadTask?.cancel()
      myImageView?.image = nil
    }
}

Don't forget to make an extension for NSCache Like this:

import Foundation

extension NSCache {
  class var sharedInstance: NSCache<NSString, AnyObject> {
      let cache = NSCache<NSString, AnyObject>()
      return cache
  }
}
Dan Nichols

Use NSCache and NSOperationQueue to manage your image loading. There's a good post outlining the technique at https://stackoverflow.com/a/12721899/5271191 (It's Objective-C, but the technique is the same for Swift.)

I highly recommend you to use a clean in place replacement/extension for UIImageView, that will manage caching of the image all transparently to you and avoid unwanted complexity of maintaining operation queues, etc.

If in memory caching suffices your needs - check this out-

https://github.com/nicklockwood/AsyncImageView

If you want persistent caching, then this one will do-

https://github.com/rs/SDWebImage

HTH.

I have images in my collectionViewCell's that are fetched and parsed via NSURLRequest, how do I cache these images so they don't have to start a new request with every single appearance/disappearance of the view?

The URL loading system already provides a cache. Take a look at the docs for NSURLCache. If the resources you need aren't already being sufficiently cached, you probably only need to adjust the disk space allocated to the URL cache for your app.

You should also take a look at the headers (cache-control, expires, etc.) that come back with your resources to make sure that they're not preventing caching. Here's a short tutorial on cache-related headers.

kean

You should use a specialized framework for that. I would not recommend using SDWebImage, it is very outdated and is not stable.

Take a look at those two libraries that are up to date with iOS platform:

  • DFImageManager - advanced framework written in Objective-C but featuring nullability annotations (works great with Swift). Here's a list of things that make it better, than SDWebImage. Disclosure: it's written by me, opinion might be biased.
  • Kingfisher - lightweight library written in Swift. Similar to SDWebImage, but has much less features that SDWebImage and DFImageManager.

I have created a library using swift 2 to do the request for image and cache it. it's very simple just give it a try.

https://github.com/georgehadly/GHImageCaching

all you can do is something like this ,

viewImg.getCachedImage("geo", URI: NSURL(string: "https://s-media-cache-ak0.pinimg.com/236x/8e/5a/98/8e5a98795dc2c5322cac97343a6cad6d.jpg")!) { (done) -> Void in
        if(done){
            // your extra
        }
    }

in case you want to delete all cached images

UIImageView.deleteAllCaching()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!