Reputation: 1655
I have a model that looks like this:
and want to display it in a UITableView
using an NSFetchedResultsController
. I want to list all of the Object
s for a given Owner
, grouped by Group
. For example, if we were to view the groups for some Owner Owner A
the table view might look like this:
Group A
Object A
Object B
Object C
Group B
Object A
Object D
Group C
Group D
Object C
Object E
It's also important that the Groups be ordered by their name
attribute (not shown in the schema above) and that NSFetchedResultsController
delegate methods get called whenever Objects are modified or added/removed from a Group.
Given those requirements, I have set up the NSFetchedResultsController
to fetch a bunch of Object
s with a predicate like [NSPredicate predicateWithFormat:@"ANY groups.owner = %@", someOwner]
, which throws an NSInvalidArgumentException
exception: "to-many key not allowed here". I have tried a few other predicates, but am stuck.
Any suggestions? Is this not something I should be using an NSFetchedResultsController
for? Or is there a better way to model my data?
Thanks!
Edit: I actually got the predicate working with the above code, my mistake was in my sectionNameKeyPath
argument. I was trying to pass in groups.name
, which was what was producing the error. I can see why that way wouldn't work, but am struggling to find a different way to achieve the desired results. Perhaps a join object?
Edit 2: This works somewhat well with a join object like this:
There are two downsides that I see now. The first is that I have to enforce uniqueness myself using code. That's easy enough, but a bit of a nuisance. The second downside, that I don't yet see a way around, is that the NSFetchedResultsController
will not call its delegate for updates to Objects
anymore. I can live with that downside for now, but am happy to hear better suggestions.
Upvotes: 2
Views: 1565
Reputation: 271
You shouldn't need a join object to get at data in Many to Many relationships
See this answer: How to deal with many to many relationships with NSFetchedResultsController?
And example project: https://github.com/dmathewwws/Many-to-Many-CoreData
Upvotes: 1
Reputation: 100602
I think the problem you're going to see is that if you have a fetched results controller searching for Objects then it's going to find each Object only exactly once. So each object will appear exactly once in your table. Whereas what you sort of want to do is invert things and find all the Groups, then displaying all the relevant contained Objects. In terms of the fetched results controller, rather than finding rows and thereby being able to divide into sections you want to find sections and thereby figure out what to supply as rows.
The easiest thing, I think, would be to create a fetched results controller on Group and to add an intermediary object of your own that remaps those to sections and supplies group.objects (with a suitably deterministic sorting applied) as the rows per section.
If you want the rows to be dynamic then I guess the easiest thing is to create a fetched results controller per section based on the feedback of the Group controller.
If that's all getting a bit painful and you want to just write your own collection logic then you'll probably want to catch NSManagedObjectContextDidSaveNotification
and rerun your logic whenever that occurs. For memory efficiency reasons you probably want to keep hold only of the objectID
s and to get the appropriate objects only when the table view requests them via the existingObjectWithID:error:
method on the context. Core Data has a built-in caching mechanism that responds appropriately to memory warnings so that's all written for you.
Upvotes: 1