When receiving a move event from my NSFetchedResultsControllerDelegate I am getting the following exception:
controllerDidChangeContent:. attempt to perform an insert and a move to the same index path
extension MyViewController : NSFetchedResultsControllerDelegate {
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.beginUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
guard let newIndexPath else { return }
tableView.insertRows(at: [newIndexPath], with: .fade)
case .delete:
guard let indexPath else { return }
tableView.deleteRows(at: [indexPath], with: .fade)
case .update:
guard let indexPath else { return }
tableView.reloadRows(at: [indexPath], with: .fade)
case .move:
guard let indexPath, let newIndexPath else { return }
tableView.moveRow(at: indexPath, to: newIndexPath)
@unknown default:
print("...")
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.endUpdates()
}
}
There are numerous posts about this in previous versions of iOS, however nothing recent. This is also boilerplate code provided by apple on how to handle insert/update/move events. Should I really checking if the at/to index paths are the same? Or does this point to an issue somewhere else?
The error message "attempt to perform an insert and a move to the same index path" usually occurs when you try to perform both an insert and a move to the same index path within the same refresh block of a table view.
In your case, you seem to be handling the move events correctly, but it could be that the NSFetchedResultsControllerDelegate is misinterpreting the move operation as an insert operation.
To solve this problem, you can change your didChange method to treat the move operation differently. Instead of treating it as an insertion or deletion, you can first delete the row at the old index path and then insert it at the new index path.
Here you can see how to customise your code to handle move operations:
By explicitly deleting the row at the old index path and then inserting it at the new index path within the same update block, you should avoid the error that occurs when you try to perform both an insert and a move at the same index path