I'm trying to use SDWebImage to download and image from an external url and return it. I do not want to set it on a view. This is the code I'm using, but it's not working. I'm returning nil. But I know the url I'm passing in works because I can see it in the browser. What am I doing wrong?
func downloadImage() -> CGImage {
var myImage: CGImage?
let myUrl = URL(string: "my-url-here.com")
SDWebImageDownloader.shared.downloadImage(with: myUrl, completed: { (image, data, error, true) in
print("Completed")
if image != nil {
myImage = image?.cgImage
}
})
return myImage!
}
I also tried this version, also with no luck:
func downloadImage() -> CGImage {
var myImage: CGImage?
let myUrl = URL(string: "my-url-here.com")
SDWebImageManager.shared.loadImage(with: myUrl, options: .continueInBackground, progress: { (received, expected, nil) in
print(received, expected)
}, completed: { (downloadedImage, data, error, SDImageCacheType, true, imageUrlString) in
DispatchQueue.main.async {
if downloadedImage != nil {
myImage = downloadedImage?.cgImage
}
}
})
return myImage!
}
SDWebImage is an asynchronous library. You can’t just return
the results. Generally one would use an @escaping
closure to supply the results to the caller. E.g.
func downloadImage(completion: @escaping(CGImage?) -> Void) {
let url = URL(string: "https://my-url-here.com")!
SDWebImageDownloader.shared.downloadImage(with: url) { image, _, _, _ in
completion(image?.cgImage)
}
}
And you’d use it like:
downloadImage { image in
guard let image = image else { return }
// use image here
}
// but not here
But let’s step back and look at the whole pattern. You say you want to “save” the result. If you’re talking about saving it to persistent storage, you would not want to use CGImage
(or UIImage
or whatever) at all. That’s computationally inefficient (converting asset to image and then back to Data
so you can save it), space inefficient (you have to load the whole asset into memory at the same time), and likely introduces problems (e.g. if you download a JPG, convert to CGImage
and then try to recreate a JPG, the resulting asset will be slightly different, bigger, and/or with new JPG artifacts). If you’re just pre-downloading assets, just use a simple networking library like Alamofire or URLSession
.