Swift 3:从URL显示图像

Mic*_*ver 32 swift3

在Swift 3中,我试图从互联网上捕获图像,并拥有以下代码行:

var catPictureURL = NSURL(fileURLWithPath: "http://i.imgur.com/w5rkSIj.jpg")
var catPictureData = NSData(contentsOf: catPictureURL as URL) // nil
var catPicture = UIImage(data: catPictureData as! Data)
Run Code Online (Sandbox Code Playgroud)

我在这做错了什么?

And*_*nez 52

您的代码有以下几点:

  1. 你正在使用大量的铸造,这是不需要的.
  2. 您将URL视为本地文件URL,但情况并非如此.
  3. 您永远不会下载图像使用的URL.

我们要做的第一件事就是声明你的变量let,因为我们以后不会修改它.

let catPictureURL = URL(string: "http://i.imgur.com/w5rkSIj.jpg")! // We can force unwrap because we are 100% certain the constructor will not return nil in this case.
Run Code Online (Sandbox Code Playgroud)

然后我们需要下载该URL的内容.我们可以用这个URLSession对象做到这一点.调用完成处理程序后,我们将从UIImageWeb下载.

// Creating a session object with the default configuration.
// You can read more about it here https://developer.apple.com/reference/foundation/urlsessionconfiguration
let session = URLSession(configuration: .default)

// Define a download task. The download task will download the contents of the URL as a Data object and then you can do what you wish with that data.
let downloadPicTask = session.dataTask(with: catPictureURL) { (data, response, error) in
    // The download has finished.
    if let e = error {
        print("Error downloading cat picture: \(e)")
    } else {
        // No errors found.
        // It would be weird if we didn't have a response, so check for that too.
        if let res = response as? HTTPURLResponse {
            print("Downloaded cat picture with response code \(res.statusCode)")
            if let imageData = data {
                // Finally convert that Data into an image and do what you wish with it.
                let image = UIImage(data: imageData)
                // Do something with your image.
            } else {
                print("Couldn't get image: Image is nil")
            }
        } else {
            print("Couldn't get response code for some reason")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,您需要调用resume下载任务,否则您的任务将永远不会启动:

downloadPicTask.resume().

所有这些代码起初可能看起来有点令人生畏,但URLSessionAPI是基于块的,因此它们可以异步工作 - 如果你阻止你的UI线程几秒钟,操作系统将终止你的应用程序.

您的完整代码应如下所示:

let catPictureURL = URL(string: "http://i.imgur.com/w5rkSIj.jpg")!

// Creating a session object with the default configuration.
// You can read more about it here https://developer.apple.com/reference/foundation/urlsessionconfiguration
let session = URLSession(configuration: .default)

// Define a download task. The download task will download the contents of the URL as a Data object and then you can do what you wish with that data.
let downloadPicTask = session.dataTask(with: catPictureURL) { (data, response, error) in
    // The download has finished.
    if let e = error {
        print("Error downloading cat picture: \(e)")
    } else {
        // No errors found.
        // It would be weird if we didn't have a response, so check for that too.
        if let res = response as? HTTPURLResponse {
            print("Downloaded cat picture with response code \(res.statusCode)")
            if let imageData = data {
                // Finally convert that Data into an image and do what you wish with it.
                let image = UIImage(data: imageData)
                // Do something with your image.
            } else {
                print("Couldn't get image: Image is nil")
            }
        } else {
            print("Couldn't get response code for some reason")
        }
    }
}

downloadPicTask.resume()
Run Code Online (Sandbox Code Playgroud)

  • 我的天啊,这是我最终要去的地方; 你的反应比我预期的要多.这给了我一个巨大的快速启动.很多,非常感谢你的帮助! (7认同)

小智 30

let url = URL(string: "http://i.imgur.com/w5rkSIj.jpg")
let data = try? Data(contentsOf: url)

if let imageData = data {
    let image = UIImage(data: imageData)
}
Run Code Online (Sandbox Code Playgroud)


San*_*ill 10

使用此扩展程序并更快地下载图像.

extension UIImageView {
    public func imageFromURL(urlString: String) {

        let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
        activityIndicator.frame = CGRect.init(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height)
        activityIndicator.startAnimating()
        if self.image == nil{
            self.addSubview(activityIndicator)
        }

        URLSession.shared.dataTask(with: NSURL(string: urlString)! as URL, completionHandler: { (data, response, error) -> Void in

            if error != nil {
                print(error ?? "No Error")
                return
            }
            DispatchQueue.main.async(execute: { () -> Void in
                let image = UIImage(data: data!)
                activityIndicator.removeFromSuperview()
                self.image = image
            })

        }).resume()
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 8

您还可以使用Alamofire\AlmofireImage执行该任务:https: //github.com/Alamofire/AlamofireImage

代码看起来应该是这样的(基于上面链接的第一个例子):

import AlamofireImage

Alamofire.request("http://i.imgur.com/w5rkSIj.jpg").responseImage { response in
    if let catPicture = response.result.value {
        print("image downloaded: \(image)")
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然它很整洁但是安全,你应该考虑是否值得Pod开销.如果您打算使用更多图像并想添加过滤器和转换,我会考虑使用AlamofireImage


dim*_*iax 5

迅速

通过扩展扩展本机功能的良好解决方案

import Foundation
import UIKit

extension UIImage {
    convenience init?(url: URL?) {
        guard let url = url else { return nil }

        do {
            let data = try Data(contentsOf: url)
            self.init(data: data)
        } catch {
            print("Cannot load image from url: \(url) with error: \(error)")
            return nil
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法

方便初始化程序是可用的并且接受可选URL- 方法是安全的.

imageView.image = UIImage(url: URL(string: "some_url.png"))
Run Code Online (Sandbox Code Playgroud)