Swift 2.1 – Unexpectedly found nil while unwrapping an Optional on delegate method call

I have the following two ViewControllers (one is TableViewController) that
CategoryTableViewController has a delegate method which will be called when Table Cell is selected. Then CreateRecipeViewController implements this delegate method and handles the selected category string.

I’m getting fatal error: unexpectedly found nil while unwrapping an Optional at the line delegate.categoryController(self, didSelectCategory: categoryCell)

  • How to enable testability for Framework in Release mode?
  • Handling Errors in New Firebase and Swift
  • Subtract minutes from NSDate
  • Does Swift use message dispatch for methods?
  • Countdown with several decimal slots, using NSTimer in Swift
  • (Firebase) printing wrong number of users in database when counting users in array
  • print(categoryCell) correctly prints the string value of selected table cell so I’m not sure why I’m getting this error.

    I’m new to implementing protocol so there may be a high chance I’m doing this wrong. I’d much appreciate if some one can give me a clue of this error.

    CategoryTableViewController (choose category)

    protocol CategoryTableViewControllerDelegate: class {
        func categoryController(controller: CategoryTableViewController, didSelectCategory category: String)
    }
    
    class CategoryTableViewController: UITableViewController {
    
        ...
    
        weak var delegate: CategoryTableViewControllerDelegate!
    
        ...
    
        override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {        
    
            if let categoryCell = recipeCategory[indexPath.row].name {
                print(categoryCell)
                delegate.categoryController(self, didSelectCategory: categoryCell)
            }
        }
    
    }
    

    CreateRecipeViewController (receives selected category)

    extension CreateRecipeViewController: CategoryTableViewControllerDelegate {
        func categoryController(controller: CategoryTableViewController, didSelectCategory category: String) {
    
            let selectedCategory = category
            dismissViewControllerAnimated(true, completion: nil)
    
            let cell = RecipeCategoryCell()
            cell.configureSelectedCategoryCell(selectedCategory)
    
            recipeCategoryTableView.reloadData()
        }
    }
    

    UPDATE

    enter image description here

    Solutions Collect From Internet About “Swift 2.1 – Unexpectedly found nil while unwrapping an Optional on delegate method call”

    The problem is that you forgot to assign a value to the property delegate. In other words, delegate is nil.

    Since delegate is an implicitly unwarped optional type, you don’t need to add a question mark or an exclamation mark to unwrap it. This is why you didn’t see the mistake.

    To solve this, just put a question mark after delegate:

    delegate?.categoryController(self, didSelectCategory: categoryCell)
    

    But that doesn’t solve the problem! This way, categoryController(:didSelectCategory:) will never be called!

    Unfortunately, I cannot think of a way to pass data between view controllers using delegation. But there is a simpler way to do that.

    For simplicity, let’s call CategoryTableViewController the sender and CreateRecipeViewController the receiver.

    This is what I guess you want to do. You want the user to select a category in the sender and pass the selected category to the receiver. So in the sender, you need to call performSegueWithIdentifier, right?

    When the view is going to perform a segue, prepareForSegue is called. You need to override that method:

    override func prepareForSegue(segue: UIStoryBoardSegue) {
        if segue.identifier == "your segue's identifier" {
            let destinationVC = segue.destinationViewController as! reciever
            destinationVC.selectedCategory = self.selectedCategory
        }
    }
    

    There is some stuff that is undefined in the above code. Let’s define them now.

    The first thing is destination.selectedCategory. You add a property in the receiver:

    var selectedCategory: String!
    

    In the viewDidLoad of the receiver, you can use this property to know what the user selected. In other words, the data is passed to this property.

    The second is self.selectedCategory. Let’s define that as well, in the sender:

    var selectedCategory: String!
    

    In the tableView(:didSelectRowAtIndexPath:indexPath:) of sender, you need to assign self.selectedCategory the category selected:

    self.categorySelected = recipeCategory[indexPath.row].name
    

    And BOOM! That’s it!