Skip to content

Instantly share code, notes, and snippets.

@jaanus
Created May 14, 2019 06:57
Show Gist options
  • Save jaanus/c28fa29ba24d44e1a2fff2d62e0493e6 to your computer and use it in GitHub Desktop.
Save jaanus/c28fa29ba24d44e1a2fff2d62e0493e6 to your computer and use it in GitHub Desktop.
//
// NSFRCChangeConsolidator.swift
//
// Created by Jaanus Kase on 14/05/2019.
// Copyright © 2019 Jaanus Kase. All rights reserved.
//
import Foundation
import CoreData
/**
This class consolidates change notifications from NSFetchedResultsController, and returns them in the right order,
appropriate for consumption by NSTableView/UITableView.
Currently, only row/item changes are implemented, since I didn’t need section change processing myself.
If needed, section changes can be added with a similar approach.
How to use this in your NSFetchedResultsController:
- in controllerWillChangeContent, initialize an instance of this
- in controller:didChange, call the ingestItemChange method for each changed item
- in controllerDidChangeContent, obtain the sorted rows in the correct order and update the tableView accordingly,
then deallocate this
Based on the idea here: https://stackoverflow.com/a/56106309/49951
*/
class NSFRCChangeConsolidator {
private var rowDeletes: [IndexPath] = []
private var rowInserts: [IndexPath] = []
private var rowUpdates: [IndexPath] = []
func ingestItemChange(ofType changeType: NSFetchedResultsChangeType, oldIndexPath: IndexPath?, newIndexPath: IndexPath?) {
switch changeType {
case .insert:
self.rowInserts.append(newIndexPath!)
case .delete:
self.rowDeletes.append(oldIndexPath!)
case .move:
self.rowDeletes.append(oldIndexPath!)
self.rowInserts.append(newIndexPath!)
case .update:
self.rowUpdates.append(newIndexPath!)
@unknown default:
fatalError("Unknown change type")
}
}
/// Reverse-sorted row deletes, suitable for feeding into table views.
func sortedRowDeletes() -> [IndexPath] {
return rowDeletes.sorted { $0.item > $1.item }
}
/// Sorted row inserts, suitable for feeding into table views.
func sortedRowInserts() -> [IndexPath] {
return rowInserts.sorted { $0.item < $1.item }
}
/// Sorted row updates, suitable for feeding into table views.
func sortedRowUpdates() -> [IndexPath] {
return rowUpdates.sorted { $0.item < $1.item }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment