Home > database >  I can't make extension convenience init for UIImage
I can't make extension convenience init for UIImage

Time:01-31

I want to create UIImage(urlString: String?). There is no error when I run this code but it is not working.

extension UIImage {
    convenience init?(urlString: String?) { 
        var imageData = Data()
        guard let urlString = urlString else { return nil}
        guard let url = URL(string: urlString) else { return nil}
        URLSession.shared.dataTask(with: url) { data, response, error in
            if let error = error {
                print("Error: \(error.localizedDescription)")
                return
            }
            guard let response = response as? HTTPURLResponse else {
                print("Empty image response")
                return
            }
            print("HTTP image response code: \(response.statusCode)")
            guard let data = data else {
                print("Empty image data")
                return
            }
            imageData = data
        }.resume()
        self.init(data: imageData)
    }
}

CodePudding user response:

UIImage initializer init(data:) is a synchronous method. Your self.init(data: imageData) method is called before the async method dataTask finish its request and execute its completion handler.

What I suggest is to create an instance method extending URL and add a completion handler to it:

extension URL {
    func asyncImage(completion: @escaping (UIImage?) -> Void) {
        URLSession.shared.dataTask(with: self) { data, _, _ in
            guard let data = data, let image = UIImage(data: data) else {
                completion(nil)
                return
            }
            completion(image)
        }.resume()
    }
}

Usage:

yourURL.asyncImage { image in 
    guard let image = image else { return }
    // use image here
}

Another option is to extend UIImageView as shown in this post

  •  Tags:  
  • Related