Search code examples
swift3alamofire

Refactoring to AlamofireImage in Swift 3


I'm new to Swift3 programming and have taken over and trying to refactor an existing application from Swift 2.2 to Swift 3. I see that Alamofire has a new library AlamofireImage.

In that library I see there is an imageCache and am considering whether I should refactor the current imageCache code to use it. My question is does it have major advantages or efficiencies over the current implementation and if so what are they? Any other suggestions for improving this code would be appreciated as well.

let imageCache = AutoPurgingImageCache() appears to be a much simpler and readable implementation.

Here is the current imageCache.

class ShoppingManager {   
    static let sharedManager = ShoppingManager()
    let imageCache = NSCache<AnyObject, AnyObject>()

Here is the original Swift 2 code to load an image and cache it.

func collectionView(_ collectionView: UICollectionView, cellForItemAtIndexPath indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! ProductsCollectionViewCell

    // Configure the cell
    cell.lblProduct.text = ""
    cell.backgroundColor = UIColor.white
    cell.imgProduct.image = nil

    //load Cell Image

    let shopItem = shopItems[indexPath.row]
    cell.alamoFireRequest?.cancel()

    if let image = ShoppingManager.sharedManager.imageCache.object(forKey: shopItem.imgUrl! as AnyObject) as? UIImage {
        cell.imgProduct.image = image
    } else {
        cell.alamoFireRequest = Alamofire.request(.GET, shopItem.imgUrl!).response(completionHandler: { (_, _, data: Data?, error: NSError?) -> Void in
            if error == nil && data != nil {
                let img = UIImage(data: data!)
                cell.imgProduct.image = img
                ShoppingManager.sharedManager.imageCache.setObject(img!, forKey: shopItem.imgUrl!)
            }
        })
    }
 return cell

 }

Here is the Swift3 code I have refactored to now.

    func collectionView(_ collectionView: UICollectionView, cellForItemAtIndexPath indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! ProductsCollectionViewCell

        // Configure the cell
        cell.lblProduct.text = ""
        cell.backgroundColor = UIColor.white
        cell.imgProduct.image = nil

        //load Cell Image

        let shopItem = shopItems[indexPath.row]
        cell.alamoFireRequest?.cancel()

    if let image = ShoppingManager.sharedManager.imageCache.object(forKey: shopItem.imgUrl! as AnyObject) as? UIImage {
        cell.imgProduct.image = image
    } else {
        cell.alamoFireRequest = Alamofire.request(shopItem.imgUrl!).responseImage { response in
           guard let img = response.result.value else {
            // Handle error
            return
        }
           cell.imgProduct.image = img
           ShoppingManager.sharedManager.imageCache.setObject(img, forKey: shopItem.imgUrl! as AnyObject)
        }              
    }

    return cell

    }

Solution

  • Did you checked their sample code.

    As per the sample code, it is quite easy:

    imageView.af_setImage(
                withURL: URL(string: URLString)!,
                placeholderImage: placeholderImage,
                filter: AspectScaledToFillSizeWithRoundedCornersFilter(size: size, radius: 20.0),
                imageTransition: .crossDissolve(0.2)
    )
    
    
    imageView.af_cancelImageRequest()
    

    Reference: https://github.com/Alamofire/AlamofireImage/blob/master/Example/ImageCell.swift

    or checkout AlamofireImageView: https://github.com/Alamofire/AlamofireImage/blob/master/Source/UIImageView%2BAlamofireImage.swift

    public func af_setImage

    This method supports caching.