NSFetchedResultsController with a predicate based on a dependent property

I have an iPhone Core Data application that displays Subscription objects, where any of its items not read . In other words, I construct the predicate as follows:

 [NSPredicate predicateWithFormat:@"ANY items.read == NO"] 

While this works for initial fetching, it does not affect Subscription objects when changing an Item , so NSFetchedResultsController never overestimates Subscription entities. What would be the best way to structure this so that the Subscription object is updated whenever the item read property is set?

I tried to create an unreadCount property on a Subscription and using keyPathsForValuesAffectingUnreadCount return a collection containing items.read . I did not expect this to work, and it is not. I get an exception from _NSFaultingMutableSet saying that the read key is not supported.

+4
source share
3 answers

I see two solutions:

  • When you modify an item, the results controller re-fetches and reloads the table view.
  • Add a property to the Subscription (for example, your unread counter or boolean hasUnreadItems) and keep it updated accordingly. Use this property in the selected result controller.

You can get a set of unread subscription items called "aSubscription" as follows:

 NSPredicate *pred = [NSPredicate predicateWithFormat:@"read == NO"]; NSSet *unreadItems = [aSubscription.items filteredSetUsingPredicate:pred]; 
+2
source

You NSFetchedResultsController an error with NSFetchedResultsController where notifications were not received (or not rated?) For changes to the properties of the associated object.

In this case, the read items property is not tracked for changes.

Instead of restructuring, you can work around this problem by faking the change in item in relation. those. when you change item.read , also pretend that you want to change item .

My experience is only one-to-one. I don’t understand how you will handle your one-to-many relationships when you only change one key of one of many. This may work:

 thisItem.read = [NSNumber numberWithBool:NO]; [thisItem.subscription willChangeValueForKey:@"items"]; [thisItem.subscription didChangeValueForKey:@"items"]; 

This should send a notification that the relationship ( subscription.items ) is changing on the subscriptions objects that are viewed by NSFetchedResultsController .

I can provide a working example of a one-to-one relationship case that works fine.

+3
source

Sorry, I should have read the question closer.

I worked in a very similar situation, setting the NSFetchedResultsController cache, and then updating the UITableView in the viewDidAppear: method. I had a fairly small data set and there was no noticeable performance hit for frequent data updates.

0
source

Source: https://habr.com/ru/post/1300082/


All Articles