0

I am trying to download an image that is uploaded to my database storage and the link to the image is in my Real time database. There is no problem with the link but when I use my method to return the image from the link I am getting nil. I force wrap it because it needs to return an image for now.

This is my code:

func getImageFromUrl(url: URL) -> UIImage {
    var tempImage: UIImage? = nil

    print("INSIDE URL -> \(url.absoluteString)")

    URLSession.shared.dataTask(with: url) { (data, response, error) in
       if error != nil {
           print("Error on getImageFromUrl : \(error!.localizedDescription)")
           return
       }

       print("Image data " + data.debugDescription)

       DispatchQueue.main.async {
           tempImage = UIImage(data: data!)!
           print("TEMP IMAGE > \(String(describing: tempImage?.images![0]))")
       }
    }.resume()

    if tempImage == nil {
        print("IMAGE IS NIL!")
    }
    return tempImage!
 }

Please let me know why my code is failing.

t4nhpt
  • 5,264
  • 4
  • 34
  • 43
  • https://stackoverflow.com/q/24231680/2303865 – Leo Dabus Aug 27 '18 at 02:45
  • 3
    the download method is asynchronous. You are returning the result before the download process is completed. What you need is to add a completion handler to your method – Leo Dabus Aug 27 '18 at 02:47

1 Answers1

1

The problem with your code is that the dataTask method is asynchronous. You are returning the result before the download process is completed. What you need is to add a completion handler to your method to return the image or the error once finished:


import UIKit
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

func getImage(from url: URL, completion: @escaping (UIImage?, Error?) -> ()) {
    print("download started:", url.absoluteString)
    URLSession.shared.dataTask(with: url) { data, reponse, error in
        guard let data = data else {
            completion(nil, error)
            return
        }
        print("download finished:")
        completion(UIImage(data: data), nil)
    }.resume()
}

let url = URL(string: "https://i.stack.imgur.com/varL9.jpg")!
getImage(from: url) { image, error in
    guard let image = image else {
        print("error:", error ?? "")
        return
    }
    print("image size:", image.size)
    // use your image here and don't forget to always update the UI from the main thread
    DispatchQueue.main.async {
        self.imageView.image = image
    }
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571