UITableView and Core Data to-many relationships - iphone

I've got a problem with UITableViews and many-to-many relationships.
I have two classes, A and B, that both extend NSManagedObject and live in Core Data. Each has a to-many relationship to the other:
A<<-->>B
I would like to use objects of class A as the sections of a UITableView, and it's set of B objects as "data rows" in the TableView. Is this possible, and what would be the best approach to achieve this? Preferably I would like to use a NSFetchedResultsController to manage the data presented by the UITableView, but so far I have not been able to come up with a predicate and section name key path that works.

You can't use a fetched results controller to do this.
If the A objects are the section names and each B objects has many A relationships then each B can show up in the table multiple times in different sections. Core Data is really set up around the idea of unique objects and all the boilerplate code for tableviews assumes that each row represents a single unique object. In this circumstance, even counting the number of rows would be difficult and the sectionNameKeyPath would be impossible to set because it could have multiple values at any one time.
You need to configure all this by hand. You'll have to fetch the A objects and then set the section titles, then you will have to get each A.bObjs and count and sort them for the rows in each section completely individually. Deleting an exist B object might prove difficult because it could trigger the removal of multiple rows at the same time.
I would urge you to rethink your design. Sections and section titles are not supposed to represent managed objects but rather a grouping of the managed objects represented by the rows based on one of the row object's attributes. What you really want here is a master-detail view hierarchy. The top tableview will show all the A objects. When a row is selected, it loads the second tableview that shows all the B objects related to the selected A object.

I would use NSFetchedResultsController to watch over the A objects. Use your fetched results to populate the section titles. Then when you are looking to populate your "data rows", you can find your current A object (by using [[fetchedResultsController fetchedResults] objectAtIndex:indexPath.section] or something similar) and extract the B objects from it with A.BOjbects, which returns the NSSet of all B objects associated with the A object. After doing that, you can filter or sort the list as you please before placing them in the rows

Related

CoreData shared entity properties

I'm new to Swift/CoreData and SQl databases. I have a CoreDatabase with over 7000 items. I want to create an entity (or any other way) to store how often a certain entry in the DB has been used. I need this in order to create a weighted sorting algorithm that suggests certain entries.
The catch is that I do not want to store this on the entries themselves, they need to remain generic in order for me to be able to update them every now and again via my own Node server. So all users have the same DB. Whenever the user picks one of the items it's counter increments by one. Whenever I query an item the frequency should come with it so I can perform a sorting algorithm on it.
I've been reading up on articles, it seems like this can be done, but none so far have been really useful. I've also looked a SQLite articles on this but haven't found what I was looking for.
I'm thinking something along these lines:
FrequencyList { Item_1 { ...7000 items....
item_1_freq : 0, ------------> frequency : 0,
item_2_freq : 12, name: "lala"
item_3_freq : 3 ...
... };
...
7000?!?!
};
Or would a separate 'meta' entity in a one-to-one relationship with it's respective Item be a good solution?
How can I tackle this?
In Core Data it would probably be better like this:
Put the selection in an entity with a count property, and have a relationship between the selection and the item. The Selection --> Item relationship could be to-one or to-many depending on your needs; I have it as to-many here but that might not be best in your case.
If you want to get the number of selections for an Item, use the value of selection.count. Update selection.count when a selection occurs.

NSFetchedResultsController fetchRequest for one-many relationship

I would really appreciate some help with using NSFetchResultsController.
I think what I am need to do should be simple for some people, but I am a bit stuck!
I will try to explain what I am doing, or a simplified version of it.
I have 2 viewControllers, each displaying an NSTableView. I am using Core Data, with an entity Clubs. One of the viewControllers displays a list of Clubs. So for this one, I create an NSFetchResultsController, passing to it a fetchRequest which is basically NSFetchRequest<Clubs>(entityName: “Clubs”).
Each club has a list of Members, with a one-many relationship). I want to display the members using the 2nd viewController. So when I tap a club in the first table, I want the second table to show its members.
I have an NSFetchResultsController connected to the second table. I am stuck at what fetchRequest to send to it. If I use a similar one to the first, i.e. NSFetchRequest<Members>(entityName: “Members”), as expected, I end up with one table showing all of the clubs stored, and the second table showing ALL members stored, whereas I want only the members in the club selected in the first table. I hope that makes sense. So my question is, what fetchRequest should I send to the 2nd tables NSFetchResultsController?
You should add the following predicate to the fetch request underlying the FRC:
fetchRequest.predicate = NSPredicate(format:"club == %#", theClubSelectedInTheFirstViewController)

NSFetchResultController: Fill TableView with fetched entity and its related entity

I have 2 entities. One describes the Section of the TableView (A Month its name, etc.) This entity is related with a one to many relationship to another entity which should describe the rows of the TableView.
I'm a bit confused how to get those entites by an NSFetchedResultController. As far as I now I can only fetch one relationship at the time. So which one should I get to fill the table properly?
If you're using NSFetchedResultsController, you fetch the objects you want to display in the table view.
To get sections, you use NSFetchedResultsController's sectionNameKeyPath property to indicate how to find a section name from one of the fetched objects. This key path is something you could pass to one of the fetched objects via valueForKeyPath: to get the section name. In your case it would require traversing a relationship back to the month entity (or whatever it really is) to get its name. For example if the relationship is called month and the Month entity has a name attribute, you would pass something like #"month.name" as the sectionNameKeyPath argument when you create the fetched results controller.
You can also use the excellent Sensible TableView framework to automatically fetch the Core Data objects and display them in a table view. The framework will also detect if the entities have any relationships and will automatically manage the detail view controllers between them.

CoreData model with nested object relationships as a datasource?

I have a very simple data model that consists of 2 objects — a Section and an Item. Each Section has a to-many child relationship to other Section objects as well as a to-one parent relationship with another Section object. Every section has a to-many relationship to Item objects.
Structure aside, some Section objects have no Item objects, and others (at the bottom of the hierarchy) have no Section child objects.
I want to create a tableview that will use Section objects to create the section headers, and then display the Item objects as tableViewCells that are a part of that Section. I also want table headers to appear if the Section has no Items, because seeing the hierarchy is important.
Given a random Section object, how would I go about fetching and displaying this data? Do I need to create a nested loop that flattens the data in an array, or is there some awesome way to leverage predicates and NSFetchedResultsController?
I would build your NSFetchedResultsController with a sort descriptor that sorts the items by the section's ID.
Something like:
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"section.ID" ascending:YES];
This will give your NSFetchedResultsController all the correct items grouped by section. Then you just need to flesh out your table view datasource and delegate accordingly.
Set your fetch entity to Item
Provide the fetch two sort descriptors. The first should sort on section.ID and the second should sort on id. That will return an array of Item objects sorted first by section and then by their own id attribute.
When initializing the fetched result controller, set the sectionNameKeyPath parameter to section.ID. That will cause the section names to display as the Section.ID values.
That should give you a table like this:
Section.ID
Item.ID
Item.ID
Item.ID
Section.ID
Item.ID
.... and so on.

Core Data - Associate a Quantity to a Relationship

I have a Core Data entity called "Item" and it represents an item in a store so it has a name, price, and a few other attributes.
I would like to be able to create lists of these items and I am having some trouble figuring out how to do it.
The problem is that I need to be able to associate a quantity for each item in the list AND I need to be able to add the item to multiple lists.
So for example, say I have an item called "Bread" and I want to add it to two different lists with different quantities associated with each relationship.
I see that the documentation for Core Data says that a userInfo dictionary can be associated with a relationship but I can't seem to locate any information that would indicate whether or not that would work for me.
Any ideas?
This is probably not the best place for a userInfo dictionary. Instead, create a new entity, which has a list releationship, an item relationship, and a quantity attribute. When you add Bread to a list, you actually add this 'link' object, and hook up the Item and List relationships, then set its quantity.