Thanks for considering to help me! so I am getting this error in the console, How should I start going about fixing it?
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An instance of NSFetchedResultsController requires a non-nil fetchRequest and managedObjectContext'
*** First throw call stack:
(0x183ff51b8 0x182a2c55c 0x18630cb90 0x1000f4eb0 0x1000f46e8 0x1000f43c8 0x1000f411c 0x1000f40e4 0x101189218 0x10118a048 0x1000f41b4 0x1000fbb94 0x1000fbc94 0x189eaa924 0x189eaa4ec 0x18a2354e4 0x18a1fc6d0 0x18a1f8b44 0x18a13bfdc 0x18a12dd50 0x189e9d0b4 0x183fa20c0 0x183f9fcf0 0x183fa0180 0x183ece2b8 0x185982198 0x189f157fc 0x189f10534 0x1000f69d0 0x182eb15b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
These are the two swift files relevant to my error:
EntryController.swift
import Foundation
import CoreData
class EntryController {
static let shared = EntryController()
var fetchResultsController: NSFetchedResultsController<Entry>
init() {
let request: NSFetchRequest<Entry> = Entry.fetchRequest()
let sortDescriptor = NSSortDescriptor(key: "timestamp", ascending: true)
request.sortDescriptors = [sortDescriptor]
fetchResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: CoreDataStack.context, sectionNameKeyPath: nil, cacheName: nil)
(try? fetchResultsController.performFetch())
}
//CRUD
func add(name: String, text: String) {
_ = Entry(name: name, text: text)
saveToPersistanceStorage()
}
func remove(entry: Entry) {
let moc = CoreDataStack.context
moc.delete(entry)
saveToPersistanceStorage()
}
func update(entry: Entry, name: String, text: String) {
entry.name = name
entry.text = text
saveToPersistanceStorage()
}
func saveToPersistanceStorage() {
let moc = CoreDataStack.context
(try? moc.save())
}
}
EntryTableListViewController.swift
import UIKit
import CoreData
class EntrylistTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
EntryController.shared.fetchResultsController.delegate = self
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let entries = EntryController.shared.fetchResultsController.fetchedObjects else {return 0}
return entries.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "entryCell", for: indexPath)
let entry = EntryController.shared.fetchResultsController.object(at: indexPath)
cell.textLabel?.text = entry.name
return cell
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let entry = EntryController.shared.fetchResultsController.object(at: indexPath)
EntryController.shared.remove(entry: entry)
}
}
//MARK: NSFetchedResultsControllerDelegate
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
guard let newIndexPath = newIndexPath else {return}
tableView.insertRows(at: [newIndexPath], with: .automatic)
case .delete:
guard let indexPath = indexPath else {return}
tableView.deleteRows(at: [indexPath], with: .automatic)
case .move:
guard let indexPath = indexPath, let newIndexPath = newIndexPath else {return}
tableView.deleteRows(at: [indexPath], with: .automatic)
tableView.insertRows(at: [newIndexPath], with: .automatic)
case .update:
guard let indexPath = indexPath else {return}
tableView.reloadRows(at: [indexPath], with: .automatic)
}
}
// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toDetailSegue" {
if let detailVC = segue.destination as? EntryDetailViewController,
let selectedRow = tableView.indexPathForSelectedRow {
let entry = EntryController.shared.fetchResultsController.object(at: selectedRow)
detailVC.entry = entry
}
}
}
}
The app creates that error as soon as the button is pressed from the main menu to segue into the EntryTableListViewController.swift. Any help will be greatly appreciated!
Additionally, here's my CoreDataStack code
import Foundation
import CoreData
enum CoreDataStack{
static let container: NSPersistentContainer = {
let appName = Bundle.main.object(forInfoDictionaryKey: (kCFBundleNameKey as String)) as! String
let container = NSPersistentContainer(name: appName)
container.loadPersistentStores() { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
return container
}()
static var context: NSManagedObjectContext { return container.viewContext }
}