Ok here goes my setup:
Object Model:
* Category object is at the root
* Product is linked to a Category (many-to-1)
* ShoppingItem is linked to a Product (many-to-1)
Application setup:
My application has a TabBarController at the root and a tableviewcontroller at the root of each of the tabs.
The first tableviewcontroller shows all ShoppingItems
It uses a NSFetchedResultsController to retrieve the data
The sortdescriptor for this controller is set as "Product.Category.Name"
The sectionNameKeyPath is set as "Product.Category.Name"
There's no predicate set
Cache name is set for this NSFRC
This helps me group the shopping items based on its product categories into sections.
The second tableviewcontroller shows all Products
It uses a NSFRC as well to retrieve the data
Sortdescriptor -- "Category.Name"
SectionNameKeyPath -- "Category.Name"
The predicate set is "Active == 1" - to load only active products
Cache name is set for this NSFRC as well
This helps me group the products based on its categories into sections.
Scenario:
When I change the category associated with a product through a third screen, the tableview which displays products refreshes itself appropriately, by reslotting the product into a different (and correct) section
But the same isn't happening on the tableview which displays the shopping items
It is not an issue with the predicates I guess, as the problem is not about missing items, it is more about the items slotted in the wrong section.
Both the tableviewcontrollers are setup the same way to be notified by the NSFRCDelegate when changes to section and row info happen.
Any clues as to what's happening here? Is this behaviour correct?
P.S. : Am # work and not able to post code snippets. Can go home and do it, if that would help.
Caching could cause a temporary problem but if you make changes to the context, the cache should be refreshed automatically. You can test for this problem by deleting the FRC cache in the view controller's viewWillAppear method. That way when you come back to the view it starts with a fresh cache every time.
I think it more likely that you have two different managed object context. You have one context for the Product table and another shared by the Change-view and ShoppingItems table.
If the ShoppingItems table and the change-view share a context, then any alterations done in the change-view will appear automatically in the ShoppingItems table but the alterations will not appear in Shopping Items table unless you merge the context's changes.
If pretty much has to be separate context because the ShoppingItems can only get its category name by walking the relationship across the Product. If ShoppingItems shows the correct category but Product that must mean that each table is accessing different versions of each Product object.
Strange problem, to say the least. Could it be that NSFetchedResultsController doesn't get notified of changes to section when using a section name key path of more than 2 levels ?
You could try the following workaround to check this point :
Add a readonly property named "categoryName" to your ShoppingItem class, with following implementation :
- (NSString *)categoryName {
return self.Product.Category.Name;
}
Then, add the following method to your ShoppingItem implementation :
+ (NSSet *)keyPathsForValuesAffectingCategoryName {
return [NSSet setWithObjects:#"Product.Category.Name", nil];
}
This will ensure that each time the name of the category changes, the KVO system will also trigger a change notification for categoryName, thus hopefully getting the NSFRC notified of the change. Of course, use categoryName as the sectionNameKeyPath of your NSFRC.
Let me know if this works.
try using different cache names for different configuration (i.e, different sort or predicate) - it should be able to return correct data. It worked from me.
Related
Good afternoon. It's not the first day I've been thinking about this task. I have a one-to-many CoreData table.
I was able to link Property to Folders. That is, folders contain many properties. A piece of code at the bottom, how to link the tables
var selectedFolder: Folders?
do {
arrayPropertys = try context.fetch(Property.fetchRequest())
arrayPropertys[indexPath.row].parentFolders = selectedFolder
}
On the main screen, I need to show the properties that are in a specific folder that is pressed. The amount I can take:
arrayPropertys[indexPath.row].parentFolders?.propertys!.count
Shows the quantity correctly. For example, there are 5 properties in one folder, and 2 properties in another.
The question is that I can't pull the attributes. There is a Name attribute, but because of the type of the NSSet object, it does not want to be shown.
I can't get the values out in any way, I've tried everything, I've read on the Internet. It doesn't work. I can see it and I can't reach it
use (parentFolders?.propertys?.allObjects as? [Property]) to access the objects as an Array<Property>
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)
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.
I have 2 entries
1. category (main one)
2. info
the relationship is 1 to many , for every category there is several info's
after i added the several info classes to each categoty
i want to get each category relationship list in the detailsviewcontroller
I created a temp class in the details view the contain the selected category
how do i get access to the list of INFO'S ??
Without seeing your code or model classes, I can't give you the exact answer. But when you made your model, you probably named your relationship something like "infosForCategory". When you generated the model it made a NSMutableSet for that 1-to-many relationship. In that case, you can access the list of infos with:
NSMutableSet *myInfos = myCategory.infosForCategory;
I'm not exactly sure what you're asking but it sounds like you already have an instance of Category and you want to retrieve all the related instances of Info. In that case, Category should have an automatically generated info property that is of the NSSet type. That set will contain all of the related Info objects.
I have an app I am working on that has 2 entities linked by a relationship (many to many). I currently have the app set up so that the rootviewcontroller controls the NSManagedObject (getting, setting, deleting of the data) in the first entity. When I drill down into on of the first entities it goes to a secondview (secondviewcontroller) that also has a table on.
When I added a NSManagedObject on this view controller I got an error, which i figured to be because I then have 2 NSManagedObjects. I then resorted to referencing the rootviewcontroller's NSManagedObject which does allow me to get and display entities in the secondview, but since it is referencing the first view it brings back first entities, not second.
How do I manage to have 2 tables on 2 view that access data from entity 1 and entity 2 respectively. As a sidenote, how do I get NSPredicate to filter the results of clicking a row in table 1 to show only entity 2's that are related to the entity 1 that was clicked on.
Sorry for the massive explanation, but it is complicated (to me) and I need to figure it out as I have been doing this for over 3 days and no googling, books, blogs etc have gone into the detail I need! I must be missing something obvious!
Overview:
Entity 1:
name
relationship 1
Entity 2:
name
relationship 1;
rootviewcontroller:
has NSManagedObject
table populated with entity 1's
secondviewcontroller:
has table that needs to be populated with entity 2's that are related to entity 1 clicked on
Currently the instance on rootviewcontroller that is in secondviewcontroller returns a list of entity 1's not 2's.
Thanks in advance guys :)
I know I should post some code of what I have done so far, but as far as I can see what I have written must be wrong from the base up!