magicalpanda / MagicalRecord

Super Awesome Easy Fetching for Core Data!
Other
10.79k stars 1.79k forks source link

NSFetchedResultsController in saveWithBlockAndWait not calling delegate #1109

Open AndrewHartAR opened 9 years ago

AndrewHartAR commented 9 years ago

This code compiles, and should work:

override func viewDidLoad() {
    super.viewDidLoad()
    MagicalRecord.saveWithBlockAndWait {
        (context: NSManagedObjectContext!) -> Void in
        let fetchRequest = Conversation.MR_requestAllSortedBy("mostRecentMessage.eventDate", ascending: false)
        self.fetchedResultsController = NSFetchedResultsController(
            fetchRequest: fetchRequest,
            managedObjectContext: context,
            sectionNameKeyPath: nil,
            cacheName: MessagesViewController.fetchedResultsCacheName())

        NSFetchedResultsController.deleteCacheWithName(MessagesViewController.fetchedResultsCacheName())
        self.fetchedResultsController.MR_performFetch()
    }
}

I have my delegate functions declared with @objc. But they just don't get called.

If I let this live outside the saveWithBlock function, using NSManagedObjectContext.MR_context() or NSManagedObjectContext.MR_mainThreadContext(), it crashes with this error:

'+entityForName: nil is not a legal NSPersistentStoreCoordinator for searching for entity name 'Conversation''

If i use MagicalRecordStack.defaultStack()!.context as the context, as I discover it does internally in other functions when you don't specify a context, it doesn't crash. But this seems very dangerous, as it relies on this always being called on the main thread.

How am I supposed to implement NSFetchedResultsController?

AndrewHartAR commented 9 years ago

This also does not call the delegate:

override func viewDidLoad() {
    super.viewDidLoad()

    MagicalRecord.saveWithBlockAndWait {
        (context: NSManagedObjectContext!) -> Void in

        let fetchRequest = Conversation.MR_requestAllSortedBy("mostRecentMessage.eventDate", ascending: false)

        self.fetchedResultsController = NSManagedObject.MR_fetchController(
            fetchRequest,
            delegate: self,
            useFileCache: false,
            groupedBy: "mostRecentEvent.eventDate",
            inContext: context)
        self.fetchedResultsController.delegate = self
        NSFetchedResultsController.deleteCacheWithName(MessagesViewController.fetchedResultsCacheName())
        self.fetchedResultsController.MR_performFetch()

    }
}
hardikdevios commented 9 years ago

@ProjectDent i suppose you are doing totally wrong you are not passing the correct context in the the fetch controller also you are not utilizing the Magical Records methods properly

let fetchController = Conversation.MR_fetchAllSortedBy(sort_key, ascending: true, withPredicate: your_predicate, groupBy: groupby_key, delegate: self ,inContext:NSManagedObjectContext.MR_defaultContext())

pronebird commented 9 years ago

@ProjectDent You use temporary context provided by MagicalRecord.saveWithBlockAndWait. This is totally wrong. Also, you should never use saveWithBlockAndWait functions on main context as you block the UI thread for no good reason.