import UIKit import CoreData class ConverterTableViewController: UITableViewController { private var fetchedResultsController: NSFetchedResultsController<Currency>! private let coreDataManager = CurrencyCoreDataManager() private var currencyManager = CurrencyManager() override func viewDidLoad() { super.viewDidLoad() setupFetchedResultsController() } func setupFetchedResultsController() { let predicate = NSPredicate(format: "isForConverter == YES") fetchedResultsController = createCurrencyFetchedResultsController(and: predicate) fetchedResultsController.delegate = self try? fetchedResultsController.performFetch() } func createCurrencyFetchedResultsController(with request: NSFetchRequest<Currency> = Currency.fetchRequest(), and predicate: NSPredicate? = nil, sortDescriptor: [NSSortDescriptor] = [NSSortDescriptor(key: "shortName", ascending: true)]) -> NSFetchedResultsController<Currency> { request.predicate = predicate request.sortDescriptors = sortDescriptor return NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil) } // MARK: - TableView DataSource Methods override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { let currency = fetchedResultsController.sections![section] print(currency.numberOfObjects) return currency.numberOfObjects } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "converterCell", for: indexPath) as! ConverterTableViewCell let currency = fetchedResultsController.object(at: indexPath) cell.flag.image = currencyManager.showCurrencyFlag(currency.shortName ?? "notFound") cell.shortName.text = currency.shortName cell.fullName.text = currency.fullName return cell } } //MARK: - NSFetchedResultsController Delegates extension ConverterTableViewController: NSFetchedResultsControllerDelegate { func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { tableView.beginUpdates() } func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { tableView.endUpdates() } func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { if let indexPath = indexPath, let newIndexPath = newIndexPath { switch type { case .update: tableView.reloadRows(at: [indexPath], with: .none) case .move: tableView.moveRow(at: indexPath, to: newIndexPath) case .delete: tableView.deleteRows(at: [indexPath], with: .none) case .insert: tableView.insertRows(at: [indexPath], with: .none) default: tableView.reloadData() } } } }