Adrian Adrian - 1 year ago 147
iOS Question

Difficulty configuring NSFetchedResultsController in Swift 3

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

, but I'm having difficulty getting
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
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
, I'm running into trouble. My code doesn't crash, but it doesn't return
despite there being objects that match my search.

Here's how I'm creating my
in a

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)
return frc

// MARK: - View Lifecycle Methods (abbreviated)
override func viewDidLoad() {
// I've tried moving this call to viewWillAppear and viewDidAppear without success

// MARK: - Core Data Methods (abbreviated)
func fetchObjectsFromManagedObjectContext() {
do {
try fetchedResultsController.performFetch()
} catch {
print("error: \(error)")
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.

Answer Source

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

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download