43

I need to get a UIImage only instead of loading a normal UIImageView with Kingfisher library

To realize it I implemented a workaround with UIImageView:

let imageView = UIImageView()

imageView.kf_setImageWithURL(NSURL(string: cpa.imageName)!, placeholderImage: nil,
        optionsInfo: [.Transition(ImageTransition.Fade(1))],
        progressBlock: { receivedSize, totalSize in
            print("\(receivedSize)/\(totalSize)")
        },
        completionHandler: { image, error, cacheType, imageURL in
            anView!.image = image //anView IS NOT an UIImageView
            anView!.frame.size = CGSize(width: 15.0, height: 15.0)
            print("Finished")
    })

This code works perfectly, but I would like to do it in a cleaner way. Is there a method in this library to get an UIImage only? Async and cached

Patonz
  • 754
  • 1
  • 5
  • 17

7 Answers7

77

You could use the retrieveImage(with:options:progressBlock: completionHandler:) method of KingfisherManager for this.

Maybe something like this:

KingfisherManager.shared.retrieveImage(with: url, options: nil, progressBlock: nil, completionHandler: { image, error, cacheType, imageURL in
    print(image)
})
Jakub Truhlář
  • 15,319
  • 7
  • 65
  • 73
onevcat
  • 4,421
  • 1
  • 19
  • 29
33

This is latest syntax to download image in kingFisher 5 (Tested in swift 4.2)

func downloadImage(`with` urlString : String){
    guard let url = URL.init(string: urlString) else {
        return
    }
    let resource = ImageResource(downloadURL: url)

    KingfisherManager.shared.retrieveImage(with: resource, options: nil, progressBlock: nil) { result in
        switch result {
        case .success(let value):
            print("Image: \(value.image). Got from: \(value.cacheType)")
        case .failure(let error):
            print("Error: \(error)")
        }
    }
}

How to call above function

self.downloadImage(with: imageURL) //replace with your image url
Hardik Thakkar
  • 13,424
  • 2
  • 80
  • 72
  • resource is a URL("url-string") object, so for anyone coming from another language it is not clear. Also, you could remove parameters where you send nil, and you could remove the completion hanlder when you don't care about the image don't loading. – sgelves May 19 '19 at 14:53
11

With the new Swift 3 version you can use ImageDownloader :

ImageDownloader.default.downloadImage(with: url, options: [], progressBlock: nil) {
    (image, error, url, data) in
    print("Downloaded Image: \(image)")
}

ImageDownloader is a part of Kingfisher so don't forget to import Kingfisher.

Argus
  • 1,653
  • 1
  • 18
  • 20
Paweł
  • 1,081
  • 1
  • 11
  • 24
  • 5
    This would not leverage the cache as per this [line](https://github.com/onevcat/Kingfisher/blob/743e3f2a54408de212d8ec74a5c91747b6a26f7e/Sources/ImageDownloader.swift#L288) `cachePolicy: .reloadIgnoringLocalCacheData` which is the point of using Kinfisher over any other simpler method – Jaime Agudo Dec 31 '16 at 12:52
6

Another way in Kingfisher 5:

KingfisherManager.shared.retrieveImage(with: url) { result in
    let image = try? result.get().image
    if let image = image {
        ...
    }
}
aneurinc
  • 1,078
  • 8
  • 17
3

In Kingfisher 5

imageView.kf.setImage(with: url) { result in
   switch result {
   case .success(let value):
       print("Image: \(value.image). Got from: \(value.cacheType)")
   case .failure(let error):
       print("Error: \(error)")
   }
 } 

see more: https://github.com/onevcat/Kingfisher/wiki/Kingfisher-5.0-Migration-Guide

Hardik Thakkar
  • 13,424
  • 2
  • 80
  • 72
Quyen Anh Nguyen
  • 184
  • 1
  • 12
3

Swift 5:

I will complete on @Hardik Thakkar answer to add a change so that you can return the image using a closure may that helps somebody:

func downloadImage(with urlString : String , imageCompletionHandler: @escaping (UIImage?) -> Void){
        guard let url = URL.init(string: urlString) else {
            return  imageCompletionHandler(nil)
        }
        let resource = ImageResource(downloadURL: url)
        
        KingfisherManager.shared.retrieveImage(with: resource, options: nil, progressBlock: nil) { result in
            switch result {
            case .success(let value):
                imageCompletionHandler(value.image)
            case .failure:
                imageCompletionHandler(nil)
            }
        }
    }

How to call:

 downloadImage(with :yourUrl){image in
     guard let image  = image else { return}
      // do what you need with the returned image.
 }
Hardik Thakkar
  • 13,424
  • 2
  • 80
  • 72
Mina Farid
  • 2,327
  • 4
  • 22
  • 34
-1

Swift 5 this code is 100% working

let url = URL(string: USER_IMAGE_PATH + "\(arrGuserpic[index])")
            
cell.imgv.kf.setImage(with: url, placeholder: nil, options: nil, progressBlock: nil, completionHandler: { image, error, cacheType, imageURL in
if (image != nil){
    cell.imgv.image = image
} 
else {
    cell.imgv.image = UIImage.init(named: "user")
}
})
Shakeel Ahmed
  • 3,089
  • 24
  • 24