Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save arashkashi/89a34aaf0d6ac653607b97d30aa123fc to your computer and use it in GitHub Desktop.
Save arashkashi/89a34aaf0d6ac653607b97d30aa123fc to your computer and use it in GitHub Desktop.
automatically sync collection view with.a fetch result controller.
//
// FetchResultsControllerWithCollectionView.swift
// CoreStore
//
// Created by Arash Kashi on 2/23/17.
// Copyright © 2017 Arash K. All rights reserved.
//
import Foundation
import CoreData
import UIKit
class FetchResultsControllerWithCollectionView: NSObject, NSFetchedResultsControllerDelegate {
var collectionView: UICollectionView!
var fetchResultController: NSFetchedResultsController<NSManagedObject>
init(fetchResultController: NSFetchedResultsController<NSManagedObject>
, collectionView: UICollectionView) {
self.collectionView = collectionView
self.fetchResultController = fetchResultController
super.init()
fetchResultController.delegate = self
try? fetchResultController.performFetch()
collectionView.reloadData()
}
var blockOperations: [BlockOperation] = []
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
if type == NSFetchedResultsChangeType.insert {
NSLog("Insert Object: \(String(describing: newIndexPath))")
blockOperations.append(
BlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.insertItems(at: [newIndexPath!])
}
})
)
}
else if type == NSFetchedResultsChangeType.update {
NSLog("Update Object: \(String(describing: newIndexPath))")
blockOperations.append(
BlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.reloadItems(at: [indexPath!])
}
})
)
}
else if type == NSFetchedResultsChangeType.move {
NSLog("Move Object: \(String(describing: newIndexPath))")
blockOperations.append(
BlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.moveItem(at: indexPath!, to: newIndexPath!)
}
})
)
}
else if type == NSFetchedResultsChangeType.delete {
NSLog("Delete Object: \(String(describing: newIndexPath))")
blockOperations.append(
BlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.deleteItems(at: [indexPath!])
}
})
)
}
}
public func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
if type == NSFetchedResultsChangeType.insert {
NSLog("Insert Section: \(sectionIndex)")
blockOperations.append(
BlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.insertSections(NSIndexSet(index: sectionIndex) as IndexSet)
}
})
)
}
else if type == NSFetchedResultsChangeType.update {
NSLog("Update Section: \(sectionIndex)")
blockOperations.append(
BlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.reloadSections(NSIndexSet(index: sectionIndex) as IndexSet)
}
})
)
}
else if type == NSFetchedResultsChangeType.delete {
NSLog("Delete Section: \(sectionIndex)")
blockOperations.append(
BlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.deleteSections(NSIndexSet(index: sectionIndex) as IndexSet)
}
})
)
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
collectionView!.performBatchUpdates({ () -> Void in
for operation: BlockOperation in self.blockOperations {
operation.start()
}
}, completion: { (finished) -> Void in
self.blockOperations.removeAll(keepingCapacity: false)
})
}
deinit {
for operation: BlockOperation in blockOperations {
operation.cancel()
}
blockOperations.removeAll(keepingCapacity: false)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment