Re: Using NSFetchedResultsController with many-to-many relationship
Re: Using NSFetchedResultsController with many-to-many relationship
- Subject: Re: Using NSFetchedResultsController with many-to-many relationship
- From: Steve Christensen <email@hidden>
- Date: Sat, 10 Mar 2018 13:06:04 -0800
Don't complicate your life by managing multiple NSFetchedResultsControllers.
Just create a single one that returns Club entities. For your table view data
source methods:
func numberOfSections(in tableView: UITableView) -> Int
{
return frc.fetchedObjects.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) ->
Int
{
let club = frc.fetchedObjects[section] as! Club
return club.persons.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
UITableViewCell
{
let club = frc.fetchedObjects[indexPath.section] as! Club
let person = club.person[indexPath.row]
return self.cell(forPerson: person)
}
If your Club and Person entities will remain static while the table view is
visible then you can just do the fetch once in viewDidLoad() and use the info
you get back as-is. If your app supports some kind of async changes to your
model data that affect which Clubs exist then you should implement the
NSFetchedResultController delegate methods so that you know when those changes
occur.
To watch for Person changes, you could set up KVO observing of the properties
you're interested in. When observeValue(...) is called then reverse look-up the
clubs of which the person is a member and reload cells corresponding to that
person in each of its clubs:
...
if let person = object as! Person
{
var cellsToReload = [IndexPath]()
for club in person.clubs
{
if let section = frc.fetchedObjects.index(of: club),
let row = club.persons.index(of: person)
{
let indexPath = IndexPath(row: row, section: section)
cellsToReload.append(indexPath)
}
}
if cellsToReload.count > 0
{
tableView.performBatchUpdates(
{
tableView.reloadRows(at: cellsToReload, with: .automatic)
},
completion: nil)
}
}
...
Steve
> On Mar 10, 2018, at 12:47 AM, Glen Huang <email@hidden> wrote:
>
> Hi,
>
> I have two models: Person and Club. They have a many-to-many relationship. I
> want to display all people in a table view sectioned by clubs (which means
> there might be duplicate people across sections). I wonder how to do that
> with NSFetchedResultsController? NSFetchRequest never returns the same object
> more than once.
>
> One solution I can come up with is to use multiple
> NSFetchedResultsController, one for each section(club). But in my case people
> are editable, so I’d like to also track changes. Listen to multiple
> NSFetchedResultsController seems pretty cumbersome if not impossible
> (especially with regard to the adding or removing of clubs, either because
> everyone leaves a club or a person joins a new club).
>
> I wonder if there is a direct way to achieve that or a better way to
> approximate?
>
> Best
> Glen
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden