2

I'm getting fatal error: unexpectedly found nil while unwrapping an Optional value when I segue from the cell.

Here's the code:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if indexPath.section == 1 {
        let listIngredients = recipeItem.ingredients[indexPath.row]
        selectedIngredient = listIngredients.ingredient
    }
    tableView.deselectRowAtIndexPath(indexPath, animated: false)
    performSegueWithIdentifier("showIngredientInRecipe", sender: self)


}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "showIngredientInRecipe" {
        let svc = segue.destinationViewController as! UINavigationController
        let destination = svc.topViewController as! IngredientDetailViewController

        destination.ingredientItem = selectedIngredient


        print("selectedIngredient \n \(selectedIngredient)")

    }

}

Here's what I get from the debugger:

        selectedIngredient
        nil

        selectedIngredient
        Optional(Ingredient {
            name = Rye Whiskey;
            inStock = 1;
            type = IngredientType {
                name = Spirit;
            };
        })

        fatal error: unexpectedly found nil while unwrapping an Optional value

As you can see, the selectedIngredient prints twice. First as nil, second time with the expected content. If i replace destination.ingredientItem = selectedIngredient with destination.ingredientItem = recipeItem.ingredients[0].ingredient the segue runs fine with no errors.

bearroast
  • 63
  • 5
  • Possible duplicate of [prepareForSegue getting called twice, with Attempt to present while presentation is in progress](http://stackoverflow.com/questions/14940738/prepareforsegue-getting-called-twice-with-attempt-to-present-uinavigationcontr) – Dima Aug 28 '16 at 00:55
  • Possible duplicate of [What does "fatal error: unexpectedly found nil while unwrapping an Optional value" mean?](http://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) – Cristik Aug 30 '16 at 03:59

3 Answers3

0

You're checking if indexPath's section is 1 and if it's not it will still perform segue. Make sure your selectable cells are in section 1 (or section 0?) and move your performSegueWithIdentifier("showIngredientInRecipe", sender: self) call to if statement to make it more safe.

  • Thanks. I moved `performSegueWithIdentifier("showIngredientInRecipe", sender: self)` to the if statement, but I still get nil at first, then the expected results afterwards. – bearroast Aug 28 '16 at 00:37
  • ```let svc = segue.destinationViewController``` already gives you ```IngredientDetailViewController```I think. Could you tell at which line it gives you nil? – Paweł Kuźniak Aug 28 '16 at 00:39
0

Fixed:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "showIngredientInRecipe" {
        if let selectedIndexPath = self.tableView.indexPathForSelectedRow {
            if selectedIndexPath.section == 1 {
                let listIngredients = recipeItem.ingredients[selectedIndexPath.row]
                selectedIngredient = listIngredients.ingredient
                let svc = segue.destinationViewController as! UINavigationController
                let destination = svc.topViewController as! IngredientDetailViewController
                destination.ingredientItem = selectedIngredient
                print("selectedIngredient \n \(selectedIngredient)")
            }
        }
    }
}
bearroast
  • 63
  • 5
0
  1. Your code is error prone because you can perform segue regardless of the section
  2. A better way to get the selected item, is to call indexPathForSelectedRow() method inside of the delegate

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if indexPath.section == 1 {
         performSegueWithIdentifier("showIngredientInRecipe", sender: self)
    }
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "showIngredientInRecipe" {
        //get selected item
        let indexPath = self.tableView.indexPathForSelectedRow() {
            let selectedIngredient = recipeItem.ingredients[indexPath.row]
            print("selectedIngredient \n \(selectedIngredient)")
            //segue
            let svc = segue.destinationViewController as! UINavigationController
            let destination = svc.topViewController as! IngredientDetailViewController
            destination.ingredientItem = selectedIngredient
        }
    }
}
meda
  • 45,103
  • 14
  • 92
  • 122