TableView UserDefaults 'unexpectedly found nil while unwrapping an Optional value'

Hello there!


I am currently facing a relatively big problem of mine, and I can't seem to figure it out. You see, I am currently displaying data from my user defaults in my table view, and when I click one of these items - I get an error like this:


fatal error: unexpectedly found nil while unwrapping an Optional value


This is the code I am using;


  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "selected" {
            let VC5 : ViewControllerFive = segue.destinationViewController as! ViewControllerFive
            let indexPath = self.tableView.indexPathForSelectedRow
         
            if let nText = self.myDefs.objectForKey("Name")?.objectAtIndex(indexPath!.row) as? String{
                VC5.tText = "Your name:  " + nText
            }
            self.tableView.deselectRowAtIndexPath(indexPath!, animated: true)
        }


This seemed to work for about a week ago, until I decided to re-design my user interface completely. If it's relevant, I can also post the other code related to my table view:


func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if let defs = myDefs.objectForKey("Name") {
            return defs.count
        } else {
            return 0
        }
    }
  
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableViewCell
      
        if let label = cell.prevText{
            label.text = self.myDefs.valueForKey("Name")?.objectAtIndex(indexPath.row) as? String
        }
    }
        return cell
      
    }


Help would be greatly appreciated!

You should use objectForKey, not valueForKey.


On what line of code is the error occurring?

if let hText = self.myDefs.objectForKey("Name")?.objectAtIndex(indexPath!.row) as? String{
                VC5.tText = "Your name: " + nText <-- This line gives me an error about this optional value..
            }

That seems odd. VC5 can't be nil or it would have crashed a few lines up when you initially tried to force downcast the destinationViewController, and nText can't be nil because it's in an if let. I suspect it's actually the previous line and it's indexPath that's nil. Are you deselecting the row in didSelectRowAtIndexPath?

I would set a breakpoint on that line and examine some stuff. My guess would be that tText could be nil.

Yes, I do also find this strange. I got this error after removing/re-adding components to my view controllers because I was updating the user interface. However, I am quite sure that's not the case either. It prints the correct text selected that I want to be displayed at the ViewController5, but I get this error about unwrapping optional value..


Somehow the error gets shown on the line above:

if let hText = self.myDefs.objectForKey("LagretDatoer")?.objectAtIndex(indexPath!.row) as? String{


And yes, I also tried objectForKey as you can see.

I could maybe do an if/else to see if the error stil persists. Will update.

I have now tried to play around with the indexPath, and it looks like it is something strange happening with it. When I removed all the code in the "prepareForSegue", and just ran this code on the selection:


It worked, but nothing showed up - as expected. However, when I tried to just print "indexPath!.row", in the prepareForSegue - I got an error. What would you suggest me to do, to get this working? here is the code for both:


func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
       self.performSegueWithIdentifier("selected", sender: self)
    }
   
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "selected" {
            let VC5 : ViewControllerFive = segue.destinationViewController as! ViewControllerFive
            let indexPath = self.tableView.indexPathForSelectedRow
           
            print(indexPath!.row)
        }

printing the indexPath in the tableView didSelectRowAtIndexPath seems to work, but not the prepareForSegue. Any ideas?

Perhaps your segue is being triggered before didSelectRowAtIndexPath is called. Myself I prefer to define the segue from VC to VC, as opposed to from a button or table cell, and programmatically initiate it (performSegueWithIdentifier) from didSelectRowAtIndexPath, passing the NSIndexPath as the sender (or better yet, the data model object corresponding to the index path).

TableView UserDefaults 'unexpectedly found nil while unwrapping an Optional value'
 
 
Q