【问题标题】:Showing image from URL in iOS app [duplicate]在 iOS 应用程序中显示来自 URL 的图像 [重复]
【发布时间】:2018-07-28 05:47:28
【问题描述】:

编辑 3:另请阅读我在“已回答”标记的答案中的评论。我想我不会使用我的同步方法,而是改用同样给出的建议异步方法!

好的,我正在努力解决一些基本概念,即在我的应用上显示来自 Internet 的 URL 的图像。

我使用此代码在我的 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 下载整个图片还是只是将其“定位”到 UIImageView 中?

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

编辑 2: 因为我的问题被标记为与另一个类似的更多解释: 我已经阅读了有关同步和异步下载的内容,并且我知道同步加载的缺点。

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

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

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

【问题讨论】:

    标签: ios swift download uiimageview


    【解决方案1】:

    切勿使用Data(contentsOf:) 显示来自远程 URL 的数据。 Data 的初始化程序是同步的,仅用于将 本地 URL 加载到您的应用中,而不是远程 URL。使用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
    })
    

    【讨论】:

    • 非常感谢,这将非常有帮助,但我不确定我的问题是否得到解答...请查看我在最初帖子中的编辑,想将其添加到评论,但是太长了……
    • 在“已回答”的答案中查看我的评论。我感觉有点糟糕,因为我现在可能会在我的代码中使用你的方法......但另一个答案真的是关注我所质疑的......希望我只给你一个支持就可以了......
    • @MakiCodes 在我看来你误解了download这个词的意思。您使用的代码会下载图像,是否将其存储更长时间是另一个问题,图像本身会被下载,即使在浏览器中也是如此。无论是在浏览器中还是在使用您的代码时,图像都只会下载到您设备的 RAM 中,而不是永久存储中。
    • 是的,我一开始没有做对,但我想我现在明白了!
    【解决方案2】:

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

    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()
    }
    

    【讨论】:

    • 非常感谢,这将非常有帮助,但我不确定我的问题是否得到解答...请查看我在初始帖子中的编辑,想将其添加到评论,但是太长了……
    • 在“已回答”的答案中查看我的评论。我感觉有点糟糕,因为我现在可能会在我的代码中使用你的方法......但另一个答案真的是关注我所质疑的......希望我只给你一个支持就可以了......
    猜你喜欢
    • 1970-01-01
    • 2019-10-08
    • 2016-11-05
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多