0

I am new to swift. I am loading image with url

mainImageView.setImageWith(URL(string: ("https:" + (content?.imagePath)!)), placeholderImage: nil)
print("dimensions after loading \(String(describing: mainImageView.image?.size))")

In case, I print the dimensions of the image as shown above then dimensions come out to be 21*6.5. However, if I wait for sometime and then print the dimensions are 188*109. How do I add a completion block to setImageWith so that I can come to know when image has finished loading?

A_G
  • 2,260
  • 3
  • 23
  • 56
  • 2
    Look at this link with accepted answer or any one you wish https://stackoverflow.com/questions/24231680/loading-downloading-image-from-url-on-swift as you are new in Swift, I would suggest read out URLSession for better future :) – Gagan_iOS Aug 23 '17 at 11:47
  • Are you using a extern lib ? Or did you wrote yourself that method? Because the extern lib could contains the method with the block (it's the case for SDWebImage that provides many, one with the closure, one without, etc.). – Larme Aug 23 '17 at 11:58

4 Answers4

2

You can use Sdwebimage for loading the image with completion block https://github.com/rs/SDWebImage

imageView.sd_setImageWithURL(NSURL(string: urlString), completed: {
                (image, error, cacheType, url) in
                // you can get the image width here...
            })
Rakesh Salian
  • 159
  • 10
0

It is happening because URL will always take a time to load image thats why first you got 21*6.5 dimensions and then got real dimensions 188*109.

As best way to prefer 3rd party library SDWebImage that will manage all the thing, You just need to set image URL.

There is method name is

open func sd_setImage(with url: URL!, placeholderImage placeholder: UIImage!, options: SDWebImageOptions = [], completed completedBlock: SDWebImage.SDWebImageCompletionBlock!)

that has completion block so you can manage whatever you want.

Govaadiyo
  • 5,644
  • 9
  • 43
  • 72
0

Convert image URL into data then Data into UIIamge, Here is a function:

func getImageFromUrl(_ strUrl: String, completionHandler handler: @escaping (_ img: UIImage) -> Void) {
    DispatchQueue.global(qos: .background).async {
        let url = URL(string: strUrl)
        let dataFromUrl = Data(contentsOf: url!)
        if dataFromUrl == nil {
            return
        }
        DispatchQueue.main.async(execute: {() -> Void in
            handler(UIImage(data: dataFromUrl!))
        })
    })
}
Anurag Sharma
  • 4,276
  • 2
  • 28
  • 44
0

Use This: -

  let imageCache = NSCache<AnyObject, AnyObject>()
 typealias CompletionHandler = (_ success:Bool, _ image:UIImage?) -> Void





 func loadImageUsingCacheWithUrlString(_ urlString: 
 String,completionHandler: @escaping CompletionHandler) {
let image = UIImage()

    //check cache for image first
    if let cachedImage = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
        image = cachedImage
        completionHandler(true, image!)
        return
    }

    if urlString.characters.count == 0 {
        completionHandler(false, image)
        return
    }

    //otherwise fire off a new download
    let url = URL(string: urlString)

    URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in

        //download hit an error so lets return out
        if error != nil {
            print(error ?? "")
            completionHandler(false,nil)
            return
        }

        DispatchQueue.main.async(execute: {
            if let downloadedImage = UIImage(data: data!) {
                image = downloadedImage
                imageCache.setObject(downloadedImage, forKey: urlString as AnyObject)                    

                completionHandler(true,image)
            }
        })

    }).resume()


}
Pushpendra
  • 976
  • 6
  • 13