¿Cómo mostrar una imagen usando URL?

El error es: “error fatal: inesperadamente encontrado nulo mientras desenvuelve un valor opcional”

Estoy haciendo lo siguiente en ViewController:

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

Realmente no entiendo por qué informará un error en

 imageURL.image = UIImage(data:data!) 

mientras que ya le dije que no proceda si los datos son nulos. No es el problema del enlace. Tampoco hay problema con los “datos”. Traté de imprimirlo y no fue nulo.

El error es más probable que imageURL sea ​​nulo. ¿Le está asignando un valor en otro lugar del código, o es realmente @IBOutlet en el código real? Si no le asigna un valor, será nulo, ¡pero su tipo de UIImageView! significa que es una “opción opcional implícitamente desenvuelta”, lo que significa que el comstackdor no impedirá su uso incluso si es nula, pero se bloqueará en el tiempo de ejecución con el error que está recibiendo.

El rest del código es correcto (¡suponiendo que falta el espacio antes != Es un error ortográfico en su código de comstackción), pero sería mejor utilizarlo if let dejáramos para desenvolver sus opcionales en lugar de verificarlos contra nil y luego usar la fuerza- desenvolver operador:

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

Si está utilizando la versión beta de Swift 1.2, puede combinar los dos factores si:

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

O, si lo prefiere, use flatMap :

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

Aquí está mi código podría ayudarte

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

Uso

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

si está utilizando una conexión HTTP y no https, no olvide agregar esto

App Transport Security Settings como diccionario y en Allow Arbitrary Loads como booleanas con el valor YES como en la figura siguiente enter image description here

Aquí tengo un enfoque desde el cual no se producirá ningún tipo de locking al descargar la imagen. Ahora está usando el siguiente código:

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

Ahora cambie el código con este, si continúa con este enfoque:

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

Y estoy seguro de que si lo usas tu nil crash será resuelto.

Puede usar SDWebImage para visualizar la imagen desde la 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"]]; 

Intenta escribir:

 if data != nil {} 

en lugar:

 if data!= nil {} 

El comstackdor puede confundir el signo de exclamación con la operación para desenvolver el valor opcional.

Puede configurar la imagen en la vista de imagen usando UIImageView + AFNetworking

A continuación, arrastre las clases del objective c de UIImageView + AFNetworking en su proyecto e importe la clase UIImageView + AFNetworking.h en el archivo de encabezado del puente de su proyecto. Y use esta línea para establecer la imagen con marcador de posición en la vista de la imagen. con esto puede establecer múltiples imágenes en una vista sin ningún problema.

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

Swift 3: (la imagen en este caso es datos binarios de 64 bits)

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

Swift 3.0 para descargar imágenes y analizar json utilizando URLSession y URLRequest.

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

Tu código es correcto, solo usa:

 if data != nil { } 

Es muy probable que estés usando Alamofire y si es así es tan simple como:

 imageView.af_setImage(withURL: url) 

Este es el código para eso. He usado esto, no necesita incluir clases ni nada más. Solo usa esta extensión. Esto es muy rápido

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

El problema es que en viewDidLoad el imageURL UIImageView puede no haber sido configurado aún. Usaría un encadenamiento opcional en caso de que el UIImageView sea nulo

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

Establecí la imagen de UIImageView en viewDidLayoutSubviews (), en ese punto está seguro de que se han configurado las salidas de ViewController.

La forma en que lo haría se vería así:

 @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: "") 

Esto devuelve un valor opcional. Eche un vistazo a la descripción de esto. Dice 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.

¡En tu código estás intentando url! que se bloqueará siempre que el valor de url sea nulo.

Methode

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

}

Uso

  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 }) 
  let urlImg = NSURL(string:"https://firebasestorage.googleapis.com/v0/b/fanism-dccfe.appspot.com/o/Heros%2FIMG-20171116-WA0003.png?alt=media&token=b31a6d9e-cea6-422a-b198-82365abd845e") data = NSData.init(contentsOf: urlImg! as URL) if data != nil { imageView?.image = UIImage(data:data! as Data) //**Here imageView our ImageView outlet **// }