Swift 3:从URL显示图像

问题描述 投票:31回答:8

在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)

我在这做错了什么?

swift3
8个回答
47
投票

您的代码有以下几点:

  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.

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

// 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")
        }
    }
}

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

downloadPicTask.resume()

所有这些代码起初可能看起来有点令人生畏,但URLSession API是基于块的,因此它们可以异步工作 - 如果你阻止你的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()

28
投票
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)
}

8
投票

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

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

7
投票

您还可以使用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)")
    }
}

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


5
投票

Swift

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

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

Usage

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

imageView.image = UIImage(url: URL(string: "some_url.png"))

4
投票

使用Alamofire在Swift 3上为我工作:

步骤1:

使用pod集成。

根据'Alamofire','〜> 4.4'

在'AlamofireImage'下,'〜> 3.3'

第2步:

导入AlamofireImage

进口Alamofire

第3步:

Alamofire.request("https://httpbin.org/image/png").responseImage { response in

if let image = response.result.value {
    print("image downloaded: \(image)")
self.myImageview.image = image
}
}

2
投票

根据我的最简单方法是使用SDWebImage

将其添加到您的pod文件中

  pod 'SDWebImage', '~> 4.0'

运行pod安装

现在导入SDWebImage

      import SDWebImage

现在从url设置图像

    imageView.sd_setImage(with: URL(string: "http://www.domain/path/to/image.jpg"), placeholderImage: UIImage(named: "placeholder.png"))

它将显示占位符图像,但是当下载图像时,它将显示来自网址的图像。您的应用程序永远不会崩溃

这是SDWebImage的主要特性

UIImageView,UIButton,MKAnnotationView的类别添加Web图像和缓存管理

异步图像下载器

具有自动缓存到期处理的异步内存+磁盘映像缓存

背景图像解压缩

保证不会多次下载相同的URL

保证不会一次又一次地重试伪造的URL

保证主线程永远不会被阻止性能!

使用GCD和ARC

要了解更多https://github.com/rs/SDWebImage


0
投票
let url = ("https://firebasestorage.googleapis.com/v0/b/qualityaudit-678a4.appspot.com/o/profile_images%2FBFA28EDD-9E15-4CC3-9AF8-496B91E74A11.png?alt=media&token=b4518b07-2147-48e5-93fb-3de2b768412d")


self.myactivityindecator.startAnimating()

let urlString = url
    guard let url = URL(string: urlString) else { return }
    URLSession.shared.dataTask(with: url)


{
(data, response, error) in
        if error != nil {
            print("Failed fetching image:", error!)
            return
        }

        guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
            print("error")
            return
        }

        DispatchQueue.main.async {
            let image = UIImage(data: data!)
        let myimageview = UIImageView(image: image)
            print(myimageview)
            self.imgdata.image = myimageview.image
self.myactivityindecator.stopanimating()

     }
  }.resume()
© www.soinside.com 2019 - 2024. All rights reserved.