Search code examples
iosswiftswift2nsurlloadimage

Swift 2 load image from url variable error


I have load_image function and works with

load_image("http://blabla.com/bla.png")

But when i add variable like this

 load_image(detailDesc2!)

gives this error

fatal error: unexpectedly found nil while unwrapping an Optional value

My codes here

ViewController table view selected codes. Here send detailDesc1 , and detailDesc 2 to DetailView Controller

  func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let subcatVC = self.storyboard?.instantiateViewControllerWithIdentifier("Detail") as! DetailViewController
        subcatVC.detailDesc1 = self.arrayCategory[indexPath.row][API_PARAM_CAT_ID] as! String
        subcatVC.detailDesc2 = self.arrayCategory[indexPath.row][API_PARAM_CAT_IMAGE] as! String
        _ = UINavigationController(rootViewController: subcatVC)
        self.navigationController?.pushViewController(subcatVC, animated: false)
    }

DetailViewController

   var detailDesc1:String?
    var detailDesc2:String?

    load_image(detailDesc2!)  // HERE GIVES ERROR

My load_image function

func load_image(urlString:String)
{
    let imgURL: NSURL = NSURL(string: urlString)!
    let request: NSURLRequest = NSURLRequest(URL: imgURL)

    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithRequest(request){
        (data, response, error) -> Void in

        if (error == nil && data != nil)
        {
            func display_image()
            {
                self.imagetbig.image = UIImage(data: data!)
            }

            dispatch_async(dispatch_get_main_queue(), display_image)
        }

    }

    task.resume()
}

Also when i add this codes success working label and textviews shows.

textbig.text = detailDesc1
textim.text = detailDesc2

Solution

  • For some reason your variable detailDesc2 is nil and you force the unwrapping using the ! telling the compiler that the variable always have a value when the variable was declared optional(it could be non-value). According to Apple:

    Trying to use ! to access a non-existent optional value triggers a runtime error. Always make sure that an optional contains a non-nil value before using ! to force-unwrap its value.

    You can avoid the runtime error using optional binding, checking before use the variable like in the following way:

    if let url = detailDesc2 {
        load_image(url)
    }
    

    As @LeoDabus recommend now in Swift 2, you can use too the guard statement that you can use like in the following way:

    guard if let url = detailDesc2 else {
       return 
    }
    
    load_image(url)
    

    According to Apple:

    A guard statement, like an if statement, executes statements depending on the Boolean value of an expression. You use a guard statement to require that a condition must be true in order for the code after the guard statement to be executed. Unlike an if statement, a guard statement always has an else clause—the code inside the else clause is executed if the condition is not true.

    I hope this help you.