Swift 如何使用SDWebImage下载和保存CGImage

Swift 如何使用SDWebImage下载和保存CGImage,swift,sdwebimage,Swift,Sdwebimage,我正在尝试使用SDWebImage从外部url下载并创建图像,然后返回它。我不想在视图上设置它。这是我正在使用的代码,但它不起作用。我是零分。但我知道我传递的url是有效的,因为我可以在浏览器中看到它。我做错了什么 func downloadImage() -> CGImage { var myImage: CGImage? let myUrl = URL(string: "my-url-here.com") SDWebImageDownloader.shared.do

我正在尝试使用SDWebImage从外部url下载并创建图像,然后返回它。我不想在视图上设置它。这是我正在使用的代码,但它不起作用。我是零分。但我知道我传递的url是有效的,因为我可以在浏览器中看到它。我做错了什么

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!
}
我也尝试过这个版本,但也不走运:

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是一个异步库。您不能只返回结果。通常,我们会使用
@转义
闭包将结果提供给调用者。例如

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)
    }
}
你会像这样使用它:

downloadImage { image in
    guard let image = image else { return }

    // use image here
}

// but not here


但让我们退一步,看看整个模式。你说你想“保存”结果。如果要将其保存到持久性存储中,则根本不想使用
CGImage
(或
UIImage
或其他任何东西)。这在计算上效率低下(将资产转换为图像,然后再转换回
数据,这样您就可以保存它),空间效率低下(您必须同时将整个资产加载到内存中),并且可能会带来问题(例如,如果您下载一个JPG,将其转换为
CGImage
,然后尝试重新创建一个JPG,则生成的资产将略有不同、更大和/或带有新的JPG工件)。如果您只是预下载资产,只需使用一个简单的网络库,如Alamofire或
URLSession

谢谢!我实际上正在尝试下载图像作为金属纹理使用。因此,我需要一个CGImage来传递到金属。或者它将允许我传递数据。我还是一个相当新的开发人员-有什么想法可以更好地做到这一点吗好的,如果你需要使用
CGImage
,那么一定要这样做。但是如果你现在真的不需要
CGImage
,只是把它转过来保存到持久存储,那么你应该避免往返于
CGImage
。用你自己的判断。(我之所以提到它,是因为我见过不止一个StackOverflow问题,其中有人下载图像,创建JPG或PNG表示,并将其保存到存储器中,这是一个非常低效的过程。但如果你不是这么做的,那么请忽略我在回答末尾的警告。)这很有效!非常感谢您的示例和解释!!