Kai
Kai

Reputation: 1477

NSFetchedResultsControllerDelegate not called when data is not matching predicate anymore

The problem I am trying to solve is the following: a predicate of an NSFetchedResultsController is restricting the results to specific conditions. But when data objects either newly satisfy or dissatisfy conditions, the NSFetchedResultsControllerDelegate is not getting called.

My NSFetchedResultsController:

private var _fetchedResultsController : NSFetchedResultsController<CardIndex>? = nil
var fetchedResultController : NSFetchedResultsController<CardIndex> {
    get {
        if _fetchedResultsController == nil {
            let fetchRequest: NSFetchRequest<CardIndex> = CardIndex.fetchRequest()
            fetchRequest.sortDescriptors = [NSSortDescriptor.init(key: "index", ascending: true)]
            fetchRequest.predicate = NSPredicate.init(format: "consumer == %@ AND card.definition != nil AND card.stateInt == 0", consumer)

            _fetchedResultsController = NSFetchedResultsController<CardIndex>.init(fetchRequest: fetchRequest, managedObjectContext: CDManager.shared.one.viewContext, sectionNameKeyPath: nil, cacheName: nil)
            do {
                try _fetchedResultsController?.performFetch()
            } catch {
                Log(.Warning, "...")
            }
            _fetchedResultsController?.delegate = self
        }

        return _fetchedResultsController!
    }
}

The data structure that is relevant here (only pseudo code):

class CardIndex {
    @NSManaged public var index: Int16
    @NSManaged public var consumer: String?
    @NSManaged public var card: CardApplication?
}

class CardApplication {
    @NSManaged public var title: String?
    @NSManaged public var indexes: NSSet?
    @NSManaged public var stateInt: NSNumber?
    @NSManaged public var definition: CardDefinition?
}

When the NSFetchedResultsController is initially fetching the data, it correctly returns all CardApplications that have a definition set and the stateInt has the value 0. But when I change the value of stateInt during runtime to another value that is not matching the predicate condition anymore, the NSFetchedResultsControllerDelegate is not being called reflecting that change in the data. I made sure that I save the managed object's context after changing the stateInt value and I can also see that the context hasChanges before saving and the CardApplication managed object is also showing the change on property changedValues(). From debugger console before saving the change, where self is the CardApplication object I changed stateInt of:

(lldb) po managedObjectContext!.hasChanges
true

(lldb) po self.isUpdated
true

(lldb) po self.changedValues()
▿ 1 element
  ▿ 0 : 2 elements
    - key : "stateInt"
    - value : 1

Why is the delegate not being called?

Upvotes: 0

Views: 63

Answers (1)

pbasdf
pbasdf

Reputation: 21536

As your FRC is configured to fetch CardIndex objects, it only observes changes to those objects. It will consequently not respond to changes to the related CardApplication objects. You could either deliberately “dirty” the CardIndex, which will trigger the FRC to re-evaluate the predicate, or abandon the FRC and use your own observer to update your UI.

Upvotes: 1

Related Questions