Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSFetchedResultsController not updating table

I've upgraded my app to Swift 2.0 and since then the NSFetchedResultsController doesn't behave correctly on iOS 8.4 (in iOS 9 it works as expected)

Scenario: - A new entity is added - Row appears in the tableview - Property of the entity is changed so it shouldn't match the predicate of the fetchedtesultscontroller - The row doesn't disappear from the tableview...

I can see the beginUpdates, the didChangeObject is called with the Delete type, and the endUpdates() is called.. My cache is nil.

Is this a known bug in xCode 7 with iOS 8.4? (the funny thing is that sometimes it DOES work, but most of the time it doesn't and it's crucial to my app...)

Thanks in advance!

p.s. I tried the if (indexPath != newIndexPath) stuff they say online, but the same result...

like image 285
CyberK Avatar asked Jan 31 '26 01:01

CyberK


2 Answers

For anyone having the same issue, here is the solution:

In your:

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {

Make sure the Update case is BEFORE the Insert case... so instead of this:

  func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
            switch type {
            case .Insert:
                self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: UITableViewRowAnimation.Fade);
            case .Move:
                if(!indexPath!.isEqual(newIndexPath!)) {
                    self.tableView.moveRowAtIndexPath(indexPath!, toIndexPath: newIndexPath!);
                }
            case .Update:
                let cell = self.tableView.cellForRowAtIndexPath(indexPath!) as! UITableViewCell;
                self.configureCell(cell, atIndexPath: indexPath!);
                self.tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Fade);
            case .Delete:
                self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Fade)
            }
        }

you should have this:

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
        switch type {
        case .Update:
            let cell = self.tableView.cellForRowAtIndexPath(indexPath!) as! UITableViewCell;
            self.configureCell(cell, atIndexPath: indexPath!);
            self.tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Fade);
        case .Insert:
            self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: UITableViewRowAnimation.Fade);
        case .Move:
            if(!indexPath!.isEqual(newIndexPath!)) {
                self.tableView.moveRowAtIndexPath(indexPath!, toIndexPath: newIndexPath!);
            }
        case .Delete:
            self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Fade)
        }
    }

It gave me a headache but finally found the solution...

like image 120
CyberK Avatar answered Feb 02 '26 15:02

CyberK


It looks like iOS 8 bug and you can find more info here: https://forums.developer.apple.com/thread/11662#65178

If you want to fix it, try this code:

public func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {

    switch type {
    case NSFetchedResultsChangeType(rawValue: 0)!:
        break // iOS 8 bug - Do nothing if we get an invalid change type.
    case .Insert:
        // Insert here
        break
    case .Delete:
        // Delete here
        break
    case .Move:
        // Move here
        break
    case .Update:
        // Update here
        break
    }
}
like image 35
Kuba Reinhard Avatar answered Feb 02 '26 13:02

Kuba Reinhard



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!