0

I want to prepare my segue via:

override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
    if segue?.identifier != "fromOpenChatsToLogIn" {
        if let controller: ChatViewController? = segue?.destinationViewController as? ChatViewController {
            if let cell: onlineUserCell? = sender as? onlineUserCell {
                let user = OneRoster.userFromRosterAtIndexPath(indexPath: tableView.indexPathForCell(cell!)!)
                controller!.recipient = user
            }
        }
    }
}

where onlineUserCell is my custom cell. Also, that's my userFromRosterAtIndexPath:

class func userFromRosterAtIndexPath(indexPath indexPath: NSIndexPath) -> XMPPUserCoreDataStorageObject {
    return sharedInstance.fetchedResultsController()!.objectAtIndexPath(indexPath) as! XMPPUserCoreDataStorageObject
}

so, when I select my cell it crashes with:

fatal error: unexpectedly found nil while unwrapping an Optional value

on line:

let user = OneRoster.userFromRosterAtIndexPath(indexPath: tableView.indexPathForCell(cell!)!)

What is wrong? How can I fix it?

Orkhan Alizade
  • 7,379
  • 14
  • 40
  • 79

4 Answers4

2

First of all, Swift introduced type inference, and the best practices is to use it properly, so write your code like this

if let controller = segue?.destinationViewController as? ChatViewController {
   if let cell = sender as? onlineUserCell {
   }
}

Also you should set an exception breakpoint in Xcode (here), to see more clearly where you're crashing.

In your case it was in

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)

You should use the following statement :

if segue.identifier == "fromOpenChatsToLogIn" {
} else {
}

Your Login ViewController doesn't require an user, therefore it crashed at

let user = OneRoster.userFromRosterAtIndexPath(indexPath: tableView.indexPathForCell(cell)!)

Because there is no cell, and the sender in prepareForSegue is definitely NOT a cell.

For you second issue, the fix was easy.

You are sending OneRoster.userFromRosterAtIndexPath(indexPath: indexPath) in

performSegueWithIdentifier("fromUsersListToChatView", sender: OneRoster.userFromRosterAtIndexPath(indexPath: indexPath))

So you don't need a cell or anything since you already have the user object !

Set the recipient like this :

controller?.recipient = sender as? XMPPUserCoreDataStorageObject

Just replace your prepareForSegue method to the following and it will work:

if segue.identifier == "fromOpenChatsToLogIn" {
} else {
    let controller = segue.destinationViewController as? ChatViewController         
    controller?.recipient = sender as? XMPPUserCoreDataStorageObject
}
Community
  • 1
  • 1
Loegic
  • 3,390
  • 20
  • 33
0

Just check, wether your cell is nil or your userFromRosterAtIndexPath return nil

Tancrede Chazallet
  • 7,035
  • 6
  • 41
  • 62
0

My advise would to set tag on each cell and then in your prepareForSegue method, get the cell, get the tag and then tweak the code for userFromRosterAtIndexPath to take that tag instead. That tag value could be row number of the cell. See if this makes sense in your context.

Abhinav
  • 37,684
  • 43
  • 191
  • 309
  • it returns `Initializer for conditional binding must have Optional type, not 'NSIndexPath'` error – Orkhan Alizade Sep 21 '15 at 06:44
  • My bad - here `indexPath` would always have some value. Could you please try once with tag approach I have suggested above. – Abhinav Sep 21 '15 at 06:50
0

Check casting like this.

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "PhotoScrollerViewController" {
        if let controller = segue.destinationViewController as? PhotoScrollerViewController {
            var cell:UICollectionViewCell = (sender as? UICollectionViewCell)!

           //Code here
        }
    }
}
BADRI
  • 643
  • 8
  • 26