How to display an image using URL?
The error is: "fatal error: unexpectedly found nil while unwrapping an Optional value"
I am doing the following in ViewController:
var imageURL:UIImageView!
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!)
}
}
I really don't understand why it will report an error on
imageURL.image = UIImage(data:data!)
while I already told it not to proceed if data is nil. It is not the problem of the link. Nor is there problem with the "data". I tried to print it and it was not nil.
Solution 1:
The error is most likely that imageURL
is nil. Are you assigning it a value elsewhere in the code, or is it actually @IBOutlet
in the real code? If you do not assign a value to it, it will be nil - but its type of UIImageView!
means it is an "implicitly unwrapped optional" which means the compiler won't stop you using it even if it is nil, but will crash at runtime with the error you're getting.
The rest of the code is correct (assuming the missing space before !=
is a typo not in your compiling code), but you would be better off using if let
to unwrap your optionals rather than checking them against nil
and then using the force-unwrap operator:
if let url = NSURL(string: "http://etc...") {
if let data = NSData(contentsOfURL: url) {
imageURL.image = UIImage(data: data)
}
}
If you happen to be using the Swift 1.2 beta, you can combine the two ifs together:
if let url = NSURL(string: "http://etc..."),
data = NSData(contentsOfURL: url)
{
imageURL.image = UIImage(data: data)
}
Or, if you prefer, use flatMap
:
imageURL.image =
NSURL(string: "http://etc...")
.flatMap { NSData(contentsOfURL: $0) }
.flatMap { UIImage(data: $0) }
Solution 2:
Here is my code might help you
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)
}
}
}
}
Usage
let imgURL = "https://yourdomain.com/picturepath/picname.png" // or jpg
self.myImage.setImageFromURl(stringImageUrl: imgURL)
if you are using HTTP connection and not https don't forget to add this
App Transport Security Settings
as dictionary and into it Allow Arbitrary Loads
as Boolean with value YES
like in the below figure
Solution 3:
Here I have an approach from which you will not get any kind of crash when downloading image. Now currently you are using the following code:
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!)
}
}
Now change the code with this one, If you are continue with this approach:
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")
}
}
And I am sure that If you are used it your nil crash will be solved.
Solution 4:
You can use SDWebImage for display image from 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"]];