Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Mr Skills

macrumors 6502a
Original poster
Nov 21, 2005
803
1
My entity "Checklist" has a to-many relationship ("checklistItems") with the entity ChecklistItem. ChecklistItem has a bool attribute called "checked".

While in my app's Checklist View, I want to find out how many of each checklist's items are checked. This is the code I have come up with:

Code:
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    Checklist *aChecklist = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = aChecklist.name;

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Checklist" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"any self.checklistItems.checked = %@", [NSNumber numberWithBool:YES]];
    [fetchRequest setPredicate:predicate];

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

    cell.detailTextLabel.text = [NSString stringWithFormat:@"%i items ticked", [results count]];
    [fetchRequest release];
}

Unfortunately, this just returns the total number of Checklists that have any item checked. What am I doing wrong?

(Thanks!)

EDIT:

I'm getting a little closer... changing the predicate to the following will give me a 1 if any item is checked, and a 0 if no item is checked. It's still not counting the number of checked items, but at least it's pointing at the right checklist.

Code:
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(name == %@) && (ANY checklistItems.checked in %@)", aChecklist.name, [NSArray arrayWithObject:[NSNumber numberWithBool:YES]]];

EDIT:

I've come up with a different way of going about it. I added a "numberChecked" attribute to my Checklist property, which I increment every time an item is ticked, a decrement every time an item is unticked.

This works fine, although I'd love to know if anyone has a way of querying this without having to make it part of my data model.
 
Last edited by a moderator:
NSManagedObjectContext allows you to count the number of items that would be found using a fetch request (instead of actually fetching those entities).

Code:
- (NSUInteger)countForFetchRequest:(NSFetchRequest *)request error:(NSError **)error

You could change your code to look like this:

Code:
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    Checklist *aChecklist = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = aChecklist.name;

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"CheckListItem" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self.checklist == %@ AND self.checked == YES", aChecklist];
    [fetchRequest setPredicate:predicate];

    NSError *error = nil;
    NSInteger numResults = [self.managedObjectContext countForFetchRequest:fetchRequest error:&error];

    cell.detailTextLabel.text = [NSString stringWithFormat:@"%i items ticked", [results count]];
    [fetchRequest release];
}

Note the change in the fetch request, predicate and the line that executes the fetch request. (I'm also assuming the name of the checklist<->checklistitem relationship in the predicate).

EDIT:

Since you have the check list you could also just filter the checkListItem set for the checklist using a predicate and take the count of filtered set. This way you don't have to fetch anything.
 
Last edited by a moderator:
Thanks @ppilone! I also asked on Stack Overflow where someone came up with the same idea of filtering the set, so that's what I've gone with. But I didn't know about "countForFetchedRequest:" so I've learned something new :)
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.