swiftcore-dataios8.3

fatal error: unexpectedly found nil while unwrapping an Optional value: Swift, Core Data


I am getting error on the line: let indexPath = self.menuTable.indexPathForSelectedRow()!. Seems that I am not getting a value from indexPathForSelectedRow. I am parsing from a CSV file into Core Data. Not sure if it matters. I am new to coding, so not sure if I am missing something obvious.

import UIKit
import CoreData

class MenuTableViewController: UITableViewController {

    @IBOutlet var menuTable: UITableView!
    private var menuItems:[MenuItem] = []
    var fetchResultController:NSFetchedResultsController!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Load menu items from database
        if let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext {
            let fetchRequest = NSFetchRequest(entityName: "MenuItem")
            var e: NSError?
            menuItems = managedObjectContext.executeFetchRequest(fetchRequest, error: &e) as! [MenuItem]
            if e != nil {
                println("Failed to retrieve record: \(e!.localizedDescription)")
            }
        }

        // Make the cell self size
        self.tableView.estimatedRowHeight = 66.0
        self.tableView.rowHeight = UITableViewAutomaticDimension
        self.tableView.layoutIfNeeded()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // Return the number of sections.
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // Return the number of rows in the section.
        return menuItems.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = menuTable.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! MenuTableViewCell

        // Configure the cell...
        cell.nameLabel.text = menuItems[indexPath.row].name
        cell.detailLabel.text = menuItems[indexPath.row].detail
//        cell.priceLabel.text = "$\(menuItems[indexPath.row].price as! Double)"

        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
    {
        self.performSegueWithIdentifier("showFront", sender: self)

    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
    {
        if (segue.identifier == "showFront")
        {
            var upcoming: CardFrontViewController = segue.destinationViewController as! CardFrontViewController

            let indexPath = self.menuTable.indexPathForSelectedRow()!

            let titleString = menuItems[indexPath.row].name

            upcoming.titleStringViaSegue = titleString

            self.menuTable.deselectRowAtIndexPath(indexPath, animated: true)

        }
    }

}

Solution

  • Since you have an implementation of tableView:didSelectRowAtIndexPath: and the cell is connected to the segue in the storyboard, the segue is happening twice. The second time the segue is performed there would be no selection because you deselect it during the first segue. You can fix this issue by deleting your implementation of tableView:didSelectRowAtIndexPath: or by creating the segue in the storyboard with the view controller itself as the source instead of the cell and leaving your manual invocation of the segue.