Forked from frr149/CoreDataTableViewController.swift
Created
February 21, 2017 23:33
-
-
Save adriencanterot/adbd0f8d0769b51996f326fef2bdbe87 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// CoreDataTableViewController.swift | |
// | |
// | |
// Created by Fernando Rodríguez Romero on 22/02/16. | |
// Copyright © 2016 udacity.com. All rights reserved. | |
// | |
import UIKit | |
import CoreData | |
class CoreDataTableViewController: UITableViewController { | |
// MARK: - Properties | |
var fetchedResultsController : NSFetchedResultsController?{ | |
didSet{ | |
// Whenever the frc changes, we execute the search and | |
// reload the table | |
fetchedResultsController?.delegate = self | |
executeSearch() | |
tableView.reloadData() | |
} | |
} | |
init(fetchedResultsController fc : NSFetchedResultsController, | |
style : UITableViewStyle = .Plain){ | |
fetchedResultsController = fc | |
super.init(style: style) | |
} | |
// Do not worry about this initializer. I has to be implemented | |
// because of the way Swift interfaces with an Objective C | |
// protocol called NSArchiving. It's not relevant. | |
required init?(coder aDecoder: NSCoder) { | |
super.init(coder: aDecoder) | |
} | |
} | |
// MARK: - Subclass responsability | |
extension CoreDataTableViewController{ | |
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { | |
fatalError("This method MUST be implemented by a subclass of CoreDataTableViewController") | |
} | |
} | |
// MARK: - Table Data Source | |
extension CoreDataTableViewController{ | |
override func numberOfSectionsInTableView(tableView: UITableView) -> Int { | |
if let fc = fetchedResultsController{ | |
return (fc.sections?.count)!; | |
}else{ | |
return 0 | |
} | |
} | |
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
if let fc = fetchedResultsController{ | |
return fc.sections![section].numberOfObjects; | |
}else{ | |
return 0 | |
} | |
} | |
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { | |
if let fc = fetchedResultsController{ | |
return fc.sections![section].name; | |
}else{ | |
return nil | |
} | |
} | |
override func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int { | |
if let fc = fetchedResultsController{ | |
return fc.sectionForSectionIndexTitle(title, atIndex: index) | |
}else{ | |
return 0 | |
} | |
} | |
override func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? { | |
if let fc = fetchedResultsController{ | |
return fc.sectionIndexTitles | |
}else{ | |
return nil | |
} | |
} | |
} | |
// MARK: - Fetches | |
extension CoreDataTableViewController{ | |
func executeSearch(){ | |
if let fc = fetchedResultsController{ | |
do{ | |
try fc.performFetch() | |
}catch let e as NSError{ | |
print("Error while trying to perform a search: \n\(e)\n\(fetchedResultsController)") | |
} | |
} | |
} | |
} | |
// MARK: - Delegate | |
extension CoreDataTableViewController: NSFetchedResultsControllerDelegate{ | |
func controllerWillChangeContent(controller: NSFetchedResultsController) { | |
tableView.beginUpdates() | |
} | |
func controller(controller: NSFetchedResultsController, | |
didChangeSection sectionInfo: NSFetchedResultsSectionInfo, | |
atIndex sectionIndex: Int, | |
forChangeType type: NSFetchedResultsChangeType) { | |
let set = NSIndexSet(index: sectionIndex) | |
switch (type){ | |
case .Insert: | |
tableView.insertSections(set, withRowAnimation: .Fade) | |
case .Delete: | |
tableView.deleteSections(set, withRowAnimation: .Fade) | |
default: | |
// irrelevant in our case | |
break | |
} | |
} | |
func controller(controller: NSFetchedResultsController, | |
didChangeObject anObject: AnyObject, | |
atIndexPath indexPath: NSIndexPath?, | |
forChangeType type: NSFetchedResultsChangeType, | |
newIndexPath: NSIndexPath?) { | |
switch(type){ | |
case .Insert: | |
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade) | |
case .Delete: | |
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade) | |
case .Update: | |
tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade) | |
case .Move: | |
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade) | |
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade) | |
} | |
} | |
func controllerDidChangeContent(controller: NSFetchedResultsController) { | |
tableView.endUpdates() | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment