// // InstancesTableViewController.swift // elpha-ios // // Created by Dwayne Harris on 8/29/18. // Copyright © 2018 Elpha. All rights reserved. // import Alamofire import CoreData import Kingfisher import UIKit class InstancesTableViewController: UITableViewController { @IBOutlet var mainNavigationItem: UINavigationItem! let fetchLimit = 20 var fetchedResultsController: NSFetchedResultsController? var loading: Bool = false { didSet { DispatchQueue.main.async { if self.loading { self.refreshControl?.beginRefreshing() } else { self.refreshControl?.endRefreshing() } } } } func initializeFetchedResultsController() { let request = NSFetchRequest(entityName: "ISInstance") request.sortDescriptors = [ NSSortDescriptor(key: "users", ascending: false), ] fetchedResultsController = NSFetchedResultsController( fetchRequest: request, managedObjectContext: CoreDataManager.shared.context, sectionNameKeyPath: nil, cacheName: nil ) fetchedResultsController!.delegate = self do { try fetchedResultsController!.performFetch() } catch { print("\(error)") } } override func viewDidLoad() { super.viewDidLoad() initializeFetchedResultsController() mainNavigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(done)) registerForPreviewing(with: self, sourceView: tableView) refreshControl?.addTarget(self, action: #selector(self.refetchInstances), for: .valueChanged) if tableView.numberOfRows(inSection: 0) == 0 { fetchInstances() } } @objc func done() { dismiss(animated: true, completion: nil) } @objc func refetchInstances() { loading = true DispatchQueue.main.async { InstancesDataManager.shared.clearInstances() CoreDataManager.shared.saveContext() InstancesDataManager.shared.reloadInstances() { error in self.loading = false } } } func fetchInstances() { loading = true DispatchQueue.main.async { InstancesDataManager.shared.loadInstances() { error in self.loading = false } } } override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { guard let count = fetchedResultsController?.fetchedObjects?.count else { return 0 } return count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: "InstancesTableViewCell", for: indexPath) as? InstancesTableViewCell else { fatalError("Unable to find reusable cell") } guard let instance = fetchedResultsController?.object(at: indexPath) else { fatalError("CoreData error") } cell.instanceNameLabel.text = instance.name cell.statusesLabel.text = NumberFormatter.localizedString(from: NSNumber(value: instance.statuses), number: .decimal) cell.usersLabel.text = NumberFormatter.localizedString(from: NSNumber(value: instance.users), number: .decimal) if let thumbnail = instance.thumbnail { cell.thumbnailImageView.kf.setImage(with: thumbnail) } if indexPath.row > 0 && indexPath.row % fetchLimit == 0 && !loading { fetchInstances() } return cell } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "InstanceDetailSegue", let cell = segue.destination as? InstanceViewController { if let indexPath = tableView.indexPathForSelectedRow { guard let instance = fetchedResultsController?.object(at: indexPath) else { fatalError("CoreData error") } cell.instance = instance } } } } extension InstancesTableViewController: UIViewControllerPreviewingDelegate { public func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) { navigationController?.pushViewController(viewControllerToCommit, animated: true) } public func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { guard let indexPath = tableView.indexPathForRow(at: location) else { return nil } guard let instance = fetchedResultsController?.object(at: indexPath) else { fatalError("CoreData error") } let storyboard = UIStoryboard(name: "Main", bundle: nil) if let detailViewController = storyboard.instantiateViewController(withIdentifier: "InstanceViewController") as? InstanceViewController { detailViewController.instance = instance return detailViewController } else { return nil } } } extension InstancesTableViewController: NSFetchedResultsControllerDelegate { func controllerDidChangeContent(_ controller: NSFetchedResultsController) { self.tableView.reloadData() } }