在iOS应用中显示来自URL的图像

时间:2018-02-17 13:09:47

标签: ios swift download uiimageview

编辑3:请同时阅读我的​​评论"已回答"标记答案。我想我不会使用我的同步方法,但改为建议的异步方法,也给出了!

好的,我正在努力解决一些基本概念,即在我的应用上从互联网上显示来自网址的图片。

我使用此代码在我的ViewController中的UIIamgeView上显示我的图像:

func showImage() {
        let myUrlImage = URL(string: linkToTheImage)
        let image = try? Data(contentsOf: myUrlImage!)
        imageView1.image = UIImage(data: image!)
    }

现在基本上我有以下问题:

是否在此过程中下载了整个图像? 或者将UIImageView作为一个"浏览器"在这种情况下,并没有下载整个图片,但只有"位置"从URL到我的UIImageView的图像?

编辑:

我问的原因是,我基本上在做一个测验应用程序,我在视图中需要的只是每个问题的URL图像 - 所以如果我做异步或同步是没有区别的,因为用户必须等待图像。我更感兴趣的是如何获得最快的结果:

所以我想知道我的代码是否真的从URL下载整个图片,或只是" Positions"它进入UIImageView?

如果在我的代码中图片以完整分辨率下载,那么你是对的,我可以在玩家开始测验时异步下载10张图片,所以他希望不必在每次回答之后等待只要他在每次回答后我同步开始下载时都会等待。

编辑2: 因为我的问题被标记为类似于另一个更多的解释: 我已经阅读过同步和异步下载,我知道同步加载的缺点。

我对一个非常基本的问题更感兴趣,我觉得我有一个基本的错误: 我最初的想法是,如果我在浏览器中打开一个链接,例如这个链接,

https://cloud.netlifyusercontent.com/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/68dd54ca-60cf-4ef7-898b-26d7cbe48ec7/10-dithering-opt.jpg

浏览器不会下载整个图片。但我想这不是这样的吗?整个图片是下载的吗?

2 个答案:

答案 0 :(得分:4)

切勿使用Data(contentsOf:)来显示远程网址中的数据。 Data的初始化程序是同步的,仅用于将本地网址加载到您的应用中,而非远程网址。使用URLSession.dataTask下载图像数据,就像使用任何其他网络请求一样。

您可以使用以下代码异步下载远程URL中的图像。

extension UIImage {
    static func downloadFromRemoteURL(_ url: URL, completion: @escaping (UIImage?,Error?)->()) {
        URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data, error == nil, let image = UIImage(data: data) else {
                DispatchQueue.main.async{
                    completion(nil,error)
                }
                return
            }
            DispatchQueue.main.async() {
                completion(image,nil)
            }
        }.resume()
    }
}

UIImageView

显示图片
UIImage.downloadFromRemoteURL(yourURL, completion: { image, error in
    guard let image = image, error == nil else { print(error);return }
    imageView1.image = image
})

答案 1 :(得分:1)

你可以这样做。但在大多数情况下,最好先自己下载图像然后处理显示(这或多或少是操作系统在后台进行的操作)。此方法也更加防故障,并允许您响应错误。

extension FileManager {

    open func secureCopyItem(at srcURL: URL, to dstURL: URL) -> Bool {
        do {
            if FileManager.default.fileExists(atPath: dstURL.path) {
                try FileManager.default.removeItem(at: dstURL)
            }
            try FileManager.default.copyItem(at: srcURL, to: dstURL)
        } catch (let error) {
            print("Cannot copy item at \(srcURL) to \(dstURL): \(error)")
            return false
        }
        return true
    }

}

func download() {
    let storagePathUrl = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("image.jpg")
    let imageUrl = "https://www.server.com/image.jpg"
    let urlRequest = URLRequest(url: URL(string: imageUrl)!)
    let task = URLSession.shared.downloadTask(with: urlRequest) { tempLocalUrl, response, error in
        guard error == nil, let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
            print("error")
            return
        }
        guard FileManager.default.secureCopyItem(at: tempLocalUrl!, to: storagePathUrl) else {
            print("error")
            return
        }
    }
    task.resume()
}