Insert and delete in UItableView sorted by date in sections (Core Data)

123 Views Asked by At

I have a requirement to implement a kind of notification center, where PUSH notifications are sorted in UITableView by date in sections. I use CoreData to store Notifications. There is a nice example by Apple that demonstrates how it can be implemented. However, it does not handle the case, when new row are added or deleted. With that example I get exceptions, especially, if multiple rows are deleted at once from several sections

error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of sections. The number of sections contained in the table view after the update (3) must be equal to the number of sections contained in the table view before the update (4), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted). with userInfo (null)

This might be an issue with transient attribute in Core Data entity... Has anybody faced already this issue? Thanks in advance.

My FetchedResultsControllerDelegate methods look like:

 // ----------------------------------------------------------------------------------------------
// MARK: - FetchedResultsController

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.beginUpdates()
}

func controller(controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
    switch type {
    case .insert:
        tableView.insertSections(NSIndexSet(index: sectionIndex) as IndexSet, with: .fade)
    case .delete:
        tableView.deleteSections(NSIndexSet(index: sectionIndex) as IndexSet, with: .fade)
    case .move:
        break
    case .update:
        break
    }
}

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    switch type {
    case .insert:
        tableView.insertRows(at: [newIndexPath! as IndexPath], with: .fade)
    case .delete:
        tableView.deleteRows(at: [indexPath! as IndexPath], with: .fade)
    case .update:
        let cell = tableView.cellForRow(at:indexPath!)
        if(cell != nil) {
            let messageCell : LPMessageCell = cell! as! LPMessageCell
            configure(cell: messageCell, atPath: indexPath!)
        }

    case .move:
        if(!self.tableView.isEditing) {
            tableView.moveRow(at: indexPath! as IndexPath, to: newIndexPath! as IndexPath)
        }
        break
    }
}

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.endUpdates()
}
0

There are 0 best solutions below