Question

My Data Model is as follows: Category

—>name

—>items (Array of items of type "Car")

I am trying to fetch with section as name and rows should be items(which is a NSArray)

Here is my code, where I am expecting to return rows as Car but it still returning "Category". So, what could be a NSFetchRequest?

NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Categories"];


NSSortDescriptor *sortDesc=[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDesc]];

fetchController=[[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:delegate.managedContext sectionNameKeyPath:@"name" cacheName:nil];
NSError *fetchError;
[fetchController performFetch:&fetchError];

I have attached image of the model.

enter image description here

Code to fetch car is as follows.

AppDelegate *del=(AppDelegate*)[UIApplication sharedApplication].delegate;
NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Car"];


NSSortDescriptor *sortDesc=[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDesc]];

fetchController=[[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:del.managedContext sectionNameKeyPath:@"Categories.name" cacheName:nil];
NSError *fetchError;
[fetchController performFetch:&fetchError];

Code is uploaded here https://www.dropbox.com/s/jjk0nve3pmytui2/TestAppData%202.zip

Note:- I am thinking to show empty section's as I have view for headers which has "Add" button. So, by this the user would know the number of categories easily.

To achieve things mentioned in the above "Note",I tried the following. I have created a CarViewController2. It creates number of sections, which are equal number of categories, but number of rows are dependent on the categoriesRelationship(which is a NSOrderedSet). One can test this by -uncommenting some code in (IBAction) addCategory:(id) sender of ViewController.m for testing. (Uncomment once , then comment again thereafter) Code has been updated and can be downloaded.

Please Correct the code if required. Thanks.

Was it helpful?

Solution

Your setup should be:

NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Car"];
NSSortDescriptor *sortDesc=[[NSSortDescriptor alloc] initWithKey:@"category.name" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDesc]];

fetchController=[[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                    managedObjectContext:delegate.managedContext 
                                                      sectionNameKeyPath:@"category.name" 
                                                               cacheName:nil];

category.name assume that the reverse relationship for Category items is Car category (one-to-many relation)

Please note that you might want to change the sort descriptor to sort by some Car property

Edit:

After you posted your model and current code you cannot section your data by Category name, as it is a many-to-many relationship.
You cannot have duplicate items for different sections.

If Car 'c' belongs to categories 'g1' and 'g2' you would either need to build the data structure yourself or introduce an intermediary entity that link between car and categories and it will be the one the request will be base upon.

Edit 2:

In your project, you set your carRelation as to-one to a Categories entity this will allow you to form the following request:

NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Car"];
NSSortDescriptor *sortDesc=[[NSSortDescriptor alloc] initWithKey:@"carName" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDesc]];

fetchController=[[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                    managedObjectContext:delegate.managedContext 
                                                      sectionNameKeyPath:@"carRelation.categoryName" 
                                                               cacheName:nil];

This would still not show categories with no cars in them (as it should as you have a cars view and a categories view).

Edit 3:

Your code corrections for CarViewController.m:

-(void) getData{
    AppDelegate *del=(AppDelegate*)[UIApplication sharedApplication].delegate;
    NSFetchRequest *req=[[NSFetchRequest alloc] initWithEntityName:@"Car"];
    NSSortDescriptor *descriptor1=[[NSSortDescriptor alloc] initWithKey:@"carRelationship.categoryName" ascending:YES];
    NSSortDescriptor *descriptor2=[[NSSortDescriptor alloc] initWithKey:@"carName" ascending:YES];
    [req setSortDescriptors:@[descriptor1,descriptor2]];
    fetchController=[[NSFetchedResultsController alloc] initWithFetchRequest:req managedObjectContext:del.managedContext sectionNameKeyPath:@"carRelationship.categoryName" cacheName:nil];
    NSError *fetchError;
    fetchController.delegate=self;
    [fetchController performFetch:&fetchError];
    NSLog(@"Fetch ERROR= %@",fetchError);
}

- (NSString*) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    id<NSFetchedResultsSectionInfo> sectionInfo=[[fetchController sections] objectAtIndex:section];
    return [sectionInfo name];
}

As I explained before, This would still not show categories with no cars in them

OTHER TIPS

Let's try

NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Category"];
NSSortDescriptor *sortDesc=[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDesc]];
fetchController=[[NSFetchedResultsController alloc] initWithFetchRequest:request   managedObjectContext:delegate.managedContext sectionNameKeyPath:@"name" cacheName:nil];
NSError *fetchError;
[fetchController performFetch:&fetchError];

NSArray *categories = [fetchedResultsController fetchedObjects];
for(Category *c in categories){
   NSSet *items = c.items;// array that you want
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top