Lapinou
Lapinou

Reputation: 1477

Select specific attribute in entity Core Data

I'm searching how to select all values for a specific attribute in an entity in Core Data.

Here my model:

I have an entity named "Countries" with 3 attributes of type "String":

I display the values on a UITableView, but I would like only show the values from name_en OR name_fr OR name_de based on the user default language. At the moment, all the values are selected (name_en, name_fr and name_de).

The solution (Thanks to Simon):

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K MATCHES %@", [NSString stringWithFormat:@"name_%@",[Config getCurrentLocale]], @".{1,}"];

Where [Config getCurrentLocale] returns me "fr" OR "de" OR "en".

Next, apply this predicate to the request:

NSFetchRequest * request = [self defaultRequest];

request.predicate = predicate;

self.fetchedResultsController = 
[[NSFetchedResultsController alloc] initWithFetchRequest:request
                                    managedObjectContext:context
                                      sectionNameKeyPath:nil
                                               cacheName:nil];

========= Relative to my problem (Resolved now) ==========

Here is my method where I build the fetch request:

-(NSFetchRequest *) defaultRequest
{

    NSFetchRequest * request = [[NSFetchRequest alloc] init];
    NSEntityDescription * entity = [NSEntityDescription entityForName:self.entityName
                                            inManagedObjectContext:appDelegate.managedObjectContext];
    NSDictionary *attributes = [entity attributesByName];

    // Put some stuff here to "filter" the request and show only name_en OR name_fr OR name_de ?
    request.entity = entity;
    request.fetchBatchSize = 20;
    //request.fetchLimit = 50;

    request.sortDescriptors = self.defaultSortDescriptors;

    return request;

}

Thank you guys for your help.

EDIT 1

Here is the data source methods of my subclass of UITableViewController:

#pragma mark - UITableView

- (NSFetchedResultsController *)fetchedResultsControllerForTableView:(UITableView *)tableView
{
    if (tableView == self.searchDisplayController.searchResultsTableView)
        return self.searchFetchedResultsController;

    if (tableView == self.tableView)
        return self.fetchedResultsController;

    return nil;
}

#pragma mark DataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [[[self fetchedResultsControllerForTableView:tableView] sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [[[[self fetchedResultsControllerForTableView:tableView] sections] objectAtIndex:section] numberOfObjects];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return [[[[self fetchedResultsControllerForTableView:tableView] sections] objectAtIndex:section] name];
}

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
    return [[self fetchedResultsControllerForTableView:tableView] sectionForSectionIndexTitle:title atIndex:index];
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    return [[self fetchedResultsControllerForTableView:tableView] sectionIndexTitles];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString * identifier = [self cellIdentifierForIndexPath:indexPath];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];

    if (cell == nil)
        cell = [self newTableViewCellWithIndentifier:identifier];

    // Configure the cell.
    [self tableView:tableView configureCell:cell atIndexPath:indexPath];

    return cell;
}

EDIT 2:

I try something like this just to show the results in outputs:

 NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Countries"];

    fetchRequest.resultType = NSDictionaryResultType;

    [fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:@"name_en", nil]];

    NSError *error      = nil;
    NSArray *results    = [[AppDelegate sharedInstance].managedObjectContext executeFetchRequest:fetchRequest error:&error];

    NSMutableArray *countries = [results valueForKey:@"name_en"];

    NSLog(@"Count: %d", countries.count);

Normally, I have around 246 countries in name_en, and the count is 757! So, the sum of name_fr + name_en + name_de... I don't understand why :(

Edit => I found a solution here: How to fetch unique field values (song_type) from core data

Now, I have to adapt my code to works with this piece of code :)

Upvotes: 0

Views: 806

Answers (1)

Simon
Simon

Reputation: 237

setPropertiesToFetch:

Specifies which properties should be returned by the fetch.

- (void)setPropertiesToFetch:(NSArray *)values

Parameters

values

An array of NSPropertyDescription objects that specify which properties should be returned by the fetch.

Discussion

The property descriptions may represent attributes, to-one relationships, or expressions. The name of an attribute or relationship description must match the name of a description on the fetch request’s entity.

Special Considerations You must set the entity for the fetch request before setting this value, otherwise NSFetchRequest throws an NSInvalidArgumentException exception.

This value is only used if resultType is set to NSDictionaryResultType.

Availability Available in iOS 3.0 and later.

Upvotes: 1

Related Questions