0

I tried to set a tableview background image, it works fine when i load image from assets. But i want to load image from web url it doesn't work.

var imageView  = UIImageView(frame:CGRect(x: 0, y: 0, width: 100, height: 200))
//let image = UIImage(named: "default_no_logo")
let image = self.fetchImage(url: "https://example.com/assets/image/store_logos/f10689d075cdfd672868c9cb4c2b9034.jpeg")
cell.backgroundColor = UIColor.clear
imageView = UIImageView(image:image)
cell.backgroundView = imageView

I have this function to download image from url, but it always return "default_no_logo", please help me.

func fetchImage(url: String) -> UIImage {
    let imageURL = URL(string: url)
    var image: UIImage?
    if let url = imageURL {
        DispatchQueue.global(qos: .userInitiated).async {
            let imageData = NSData(contentsOf: url)
            DispatchQueue.main.async {
                if imageData != nil {
                    image = UIImage(data: imageData! as Data)
                }
            }
        }
    }
  
    return image ?? UIImage(named: "default_no_logo")!
}
Peter
  • 1,860
  • 2
  • 18
  • 47
  • 1
    Never ever load data with synchronous `(NS)Data(contentsOf` from e remote URL, not even on a background thread. This is very bad practice. Use an asynchronous API and cache the images. – vadian Nov 20 '20 at 14:41

1 Answers1

0

You assing a value to image in async function but return witouth a completion handler so this function return too fast (not waiting to image loading from url ) so image always nil on that line return image ?? UIImage(named: "default_no_logo")! So If you want to load this image async you need to use a completion handler

This is the usage :

    func fetchImage(url: String , completed: @escaping (UIImage) -> ()) {
    let imageURL = URL(string: url)
    var image: UIImage?
    if let url = imageURL {
            let imageData = try? Data(contentsOf: url)
        DispatchQueue.global(qos: .userInitiated).async {

            DispatchQueue.main.async {
                if imageData != nil {
                    image = UIImage(data: imageData!)
                    completed(image!)
                    
                }
                else {
                    completed(UIImage(named: "cancel-red")!)
                }

            }
        }
    }
  
}

And when you call :

self.fetchImage(url: "https://tinyjpg.com/images/social/website.jpg", completed: { ret in
        print(ret) // ret is your image
    })
Omer Tekbiyik
  • 4,255
  • 1
  • 15
  • 27