I am trying, for learning sake, to make a hybrid database app that will allow the user to store data locally and will allow the user to connect to an external database. I have a controller (MainController.swift) file that houses the code that will interact with the Suggest Table that I have in my Main View Controller. Here is the code (sorry, its long):
import UIKit
import CoreData
class MainController: UIViewController, NSFetchedResultsControllerDelegate {
// MARK: UI Components
// Suggestions Table
@IBOutlet weak var dataTableView: UITableView!
@IBOutlet weak var suggestLabel: UILabel!
// MARK: Variables
private var suggests = [Suggest]() {
didSet {
updateMainView()
}
}
private let persistContainer = NSPersistentContainer(name: "Suggest")
fileprivate lazy var fetchedResults:NSFetchedResultsController<Suggest> = {
let fetchRequest: NSFetchRequest<Suggest> = Suggest.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "createdAt", ascending: true)]
let fetchedResults = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.persistContainer.viewContext, sectionNameKeyPath: nil, cacheName: nil)
fetchedResults.delegate = self
return fetchedResults
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
dataTableView.dataSource = self
dataTableView.delegate = self
setupMainView()
// Load persistent container modules
persistContainer.loadPersistentStores { (persistenStoreDescription, error) in
if let error = error {
print("[-] Unable to load persistent container -> \(error) : \(error.localizedDescription)")
} else {
self.setupMainView()
do {
try self.fetchedResults.performFetch()
} catch {
let fetchError = error as NSError
print("[-] Unable to perform fetch request -> \(fetchError) : \(fetchError.localizedDescription)")
}
self.updateMainView()
}
}
}
// MARK: Add-On functions and methods
private func updateMainView() {
var hashSuggest = false
if let suggests = fetchedResults.fetchedObjects {
hashSuggest = suggests.count > 0
}
dataTableView.isHidden = !hashSuggest
if hashSuggest { suggestLabel.text = "Suggested Databases" }
}
private func setupMainView() -> Void {
suggestLabel.text = defaultNoSuggestsString()
updateMainView()
}
private func defaultNoSuggestsString() -> String { return "No suggested databases...Error" }
@nonobjc public class func performFetch() -> NSFetchRequest<Suggest> {
return NSFetchRequest<Suggest>(entityName: "Suggest");
}
}
// MARK: Extensions
extension MainController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let suggests = fetchedResults.fetchedObjects else { return 0 }
return suggests.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "suggestCell", for: indexPath) as? SuggestedCellStructure else {
fatalError("Unexpected Index Path")
}
// Fetch the data modules
let module = fetchedResults.object(at: indexPath)
// Image config
let image = UIImage(systemName: module.image_string!)
let mainImage = UIImageView(image: image)
// Configure the cell
cell.suggestTitle.text = module.title_string
cell.suggestDesc.text = module.desc_string
cell.welcomingImage = mainImage
return cell
}
}
I have the Core Data structure here as well (Image 01) with the Name defined as the Class.
When every I run the app to test, I get this error message:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An instance of NSFetchedResultsController requires a non-nil fetchRequest and managedObjectContext' - terminating with uncaught exception of type NSException
The Name is defined in the Core Data Structure file and the Codegen is defined as "Class Definition" so...im not seeing what is wrong.
- Here is also the TableViewCell structure profile code:
import Foundation
import UIKit
class SuggestedCellStructure: UITableViewCell {
@IBOutlet weak var welcomingImage: UIImageView!
@IBOutlet weak var suggestTitle: UILabel!
@IBOutlet weak var suggestDesc: UITextView!
@IBOutlet weak var initSuggest: UIButton!
}