AlamofireImage cache doesn't work in my app

1.2k Views Asked by At

I am using af_setImage() to set an image to a UIImageView. I need to cache image and if it's cached, I want it not to make transition. I have tried some codes below but the image cache with identifier always returns nil. It seems that imageCache.add() is called every time but it doesn't add the cache.

    let imageCache = AutoPurgingImageCache()

    if let image = imageCache.image(withIdentifier: post.mainImage) {
        cell.postImageView.image = image
    } else {
        cell.postImageView.af_setImage(
            withURL: URL(string: post.mainImage)!,
            placeholderImage: PostCellView.defaultImage,
            imageTransition: .crossDissolve(0.5),
            completion: { response in
                if let image = response.result.value, response.result.isSuccess {
                    imageCache.add(image, withIdentifier: post.mainImage)
                }
            }
        )
    }

What am I wrong?

Thank you in advance( ´ ▽ ` )

1

There are 1 best solutions below

0
On

I found that the main issue with AutoPurgingImageCache is that the new instances do not inherit cache from the previous objects, so if you put this code inside the viewDidLoad function the cache its always return nil

So I manage to solve with a static object, this is the code


import UIKit
import AlamofireImage

class ViewController: UIViewController {

    static let imageCache = AutoPurgingImageCache(
        memoryCapacity: 900 * 1024 * 1024,
        preferredMemoryUsageAfterPurge: 600 * 1024 * 1024)

    override func viewDidLoad() {
        super.viewDidLoad()

        let image_url = Bundle.main.object(forInfoDictionaryKey: "IMAGE_URL") as! String
        let name = "/someimage.jpg"

        let url = URL(string: image_url + name)
        let urlRequest = URLRequest(url: url!)

        let img_from_cache = ViewController.imageCache.image( for: urlRequest, withIdentifier: name)

        if img_from_cache != nil{
            print("FROM CACHE!!")
            imageView.image = img_from_cache
//            self.setImageViewSize(img_from_cache!)
        }else{
            print("NOT FROM CACHE!!")
            imageView.af_setImage(
                withURL: url!,
                placeholderImage: nil,
                filter: AspectRatioScaledToWidthFilter(width: self.view.frame.size.width),
                completion :{ (rs) in
                    ViewController.imageCache.add(self.imageView.image!, for: urlRequest, withIdentifier: name)
                }
            )
        }

    }
}

/// Scales an image to a specified width and proportional height.
public struct AspectRatioScaledToWidthFilter: ImageFilter {
    /// The size of the filter.
    public let width: CGFloat
    /**
     Initializes the `AspectRatioScaledToWidthFilter` instance with the given width.
     - parameter width: The width.
     - returns: The new `AspectRatioScaledToWidthFilter` instance.
     */
    public init(width: CGFloat) {
        self.width = width
    }

    /// The filter closure used to create the modified representation of the given image.
    public var filter: (Image) -> Image {
        return { image in
            return image.af_imageScaled(to: CGSize(width: self.width, height: self.width * image.size.height / image.size.width))
        }
    }
}

Be aware that the af_setImage function already use cache, so you must use the cache object for other purpose than display a image inside a UIImage object, for example display a image inside a textView, with a NSTextAttachment