I'm refactoring an existing project from Swift 2 to Swift 3. Everything has been straightforward until I got to refactoring Core Data. I'm able to create managed objects and persist them in the managedObjectContext
, but I'm having difficulty getting NSFetchedResultsController
to work. I took a look at this post, but it's not getting me across the finish line.
After importing records from a JSON, I verify there are objects in my managedObjectContext
with the following code:
func recordCount() -> Int {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "MyEntity")
let count = try! context.count(for: fetchRequest)
return count
}
When I create a fetchedResultsController
, I'm running into trouble. My code doesn't crash, but it doesn't return NSManagedObjects
despite there being objects that match my search.
Here's how I'm creating my NSFetchedResultsController
in a UIViewController
.
class MyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate {
// This is set on a prior viewController before segue.
// I've verified it's not nil
var selectedEquipmentString: String?
let managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
lazy var fetchedResultsController: NSFetchedResultsController<MyEntity> = {
// I've tried altering the syntax of the fetchRequest
// let fetchRequest: NSFetchRequest<MyEntity> = MyEntity.fetchRequest()
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "MyEntity")
let sortDescriptor = NSSortDescriptor(key: "generalArea", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.predicate = NSPredicate(format: "equipmentDescription == %@", self.selectedEquipmentString!)
let frc: NSFetchedResultsController<MyEntity> = NSFetchedResultsController(fetchRequest: fetchRequest as! NSFetchRequest<MyEntity>, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: "generalArea", cacheName: nil)
frc.delegate = self
return frc
}()
// MARK: - View Lifecycle Methods (abbreviated)
override func viewDidLoad() {
super.viewDidLoad()
// I've tried moving this call to viewWillAppear and viewDidAppear without success
fetchObjectsFromManagedObjectContext()
}
// MARK: - Core Data Methods (abbreviated)
func fetchObjectsFromManagedObjectContext() {
do {
try fetchedResultsController.performFetch()
} catch {
print("error: \(error)")
return
}
print ("There are \(fetchedResultsController.fetchedObjects!.count) returned from fetchObjectsFromManagedObjectContext")
}
}
This code doesn't crash, but it doesn't return any records from a fetchRequest. I was able to force a crash with a typo in the predicate, but without a typo there are no objects returned despite objects that match the predicate.
I welcome any suggestions re: where my mistake is. I rest assured knowing it will be a startlingly silly oversight on my part. Thank you for reading.
Your NSFetchRequest should have a type NSFetchRequest<MyEntity>
, but you specify NSFetchRequest<NSFetchRequestResult>
. Try changing this and let me know if it helps or not