How do you sort NSNumber with NSSortDescriptor? - iphone

I'm having trouble sorting an NSNumber using NSSortDescriptor. For whatever reason it won't sort into the correct order. What am I doing wrong?
- (NSNumber *)sortNumber {
NSNumber *sum = [NSNumber numberWithFloat:([self.capacity floatValue] / [self.availability floatValue])];
return sum;
}
It is defined as an Int32 in the xcdataModel and called by this class to sort.
- (NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController == nil) {
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setReturnsObjectsAsFaults:NO];
[fetchRequest setEntity:[NSEntityDescription entityForName:#"Event" inManagedObjectContext:managedObjectContext]];
NSArray *sortDescriptors = nil;
} if ([fetchSectioningControl selectedSegmentIndex] == 0) {
sortDescriptors = [NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:#"sortNumber" ascending:YES selector:#selector(compare:)] autorelease]];
}
[fetchRequest setSortDescriptors:sortDescriptors];
EDIT:Yeah, in the cold light of day this needs a little more explanation. I'll try to explain the project. This is a CoreData app, the values 'capacity' and 'availability' are derived from parsing an XML file with SAX and attaching them to the Managed Object Model where they are defined as Strings, originally they would have been numeric in the XML.
These are then defined in a Class where the calculation above has been made and attached to the same Object Model (if the code above is right then perhaps this is where the problem is?). All this has been in effort to obtain a percentage value that I would like to use to sort a TableView. (BTW, I realise they need swapping around, oops) The second bit of code is where this happens using NSFetchResultsController and ManagedObjectContext. I know this bit works because I'm also sorting this list by other attributes set to if selectedSegmentIndex == 0 etc. They all sort correctly.
I hope this makes a bit more sense.

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"sortNumber" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
you can use NSSortDescriptor without calling compare method. It will sort itself in you desired order.

Related

Core Data - Possible to sort TableView using blocks in NSSortDescriptor?

I am trying to sort a table by an author's last name. Currently, the data is saved as a string in core data as "FirstName LastName."
I understand that custom selectors in core data are out of the scope of Cocoa and return an 'NSInvalidArgumentException', reason: 'unsupported NSSortDescriptor selector: compareToLastName:' Is this true for using a comparator as well?
Here is what I am working from that seems to ignore the comparator completely.
// Sort the request
NSSortDescriptor *sortByType;
if ([sort isEqualToString:#"author"]) {
NSComparator comparisonBlock = ^(id obj1,id obj2) {
NSString *obj1B = [[(NSString *)obj1 componentsSeparatedByString:#" "] lastObject];
NSString *obj2B = [[(NSString *)obj2 componentsSeparatedByString:#" "] lastObject];
return (NSComparisonResult) [obj1B compare: obj2B];
};
sortByType = [[NSSortDescriptor alloc] initWithKey:sort ascending:YES comparator:comparisonBlock];
}
else {
sortByType = [[NSSortDescriptor alloc] initWithKey:sort ascending:YES];
}
NSSortDescriptor *secondSort = [[NSSortDescriptor alloc] initWithKey:#"title" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortByType, secondSort, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
Thanks!
Yes this is even true for NSComparator since the sort descriptors are compiled and executed in SQL itself for performance reasons it isn't really supported.
You can read more here https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/Articles/cdPersistentStores.html#//apple_ref/doc/uid/TP40002875-SW11 under Fetch Predicates and Sort Descriptors.

CoreData Math Functions

I've got a column with integer values in CoreData. While retrieving results from it, I want the column values to be subtracted with a number.
Something like: columnValue - someNumber (this number is entered by user)
I know I may have to use NSPredicate for this, but am unaware if there's a function or syntax for it.
The alternate right now I have is to iterate all column values and subtract with 'someNumber'. But I think there should be a better and efficient way to do this.
Edit: Code from #salo.dm 's answer
- (NSDictionary *)myFetchResults {
//Predicate works fine
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:pred1, pred2, nil]];
/*Sort Descroptor - Sorting by 4 columns*/
NSSortDescriptor *sortDesc1 = [NSSortDescriptor sortDescriptorWithKey:#"Column1" ascending:YES];
NSSortDescriptor *sortDesc2 = [NSSortDescriptor sortDescriptorWithKey:#"Column2" ascending:YES];
NSSortDescriptor *sortDesc3 = [NSSortDescriptor sortDescriptorWithKey:#"Column3" ascending:YES];
NSSortDescriptor *sortDesc4 = [NSSortDescriptor sortDescriptorWithKey:#"Column4" ascending:YES];
/*Get Data*/
MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"TableName" inManagedObjectContext:context];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDesc1, sortDesc2, sortDesc3, sortDesc4, nil]];
NSArray *listData = [context executeFetchRequest:fetchRequest error:nil];
/*Create subtract expression*/
NSExpressionDescription *subExp1 = [[NSExpressionDescription alloc] init];
[subExpLatitude setName:#"subtraction1"];
[subExpLatitude setExpression:[NSExpression expressionForFunction:#"from:subtract:"
arguments:[NSArray arrayWithObjects:
[NSExpression expressionForKeyPath:#"Column3"],
[NSExpression expressionForConstantValue:[NSNumber numberWithDouble:someNumber1]],
nil]]];
[subExp1 setExpressionResultType:NSDoubleAttributeType];
NSExpressionDescription *subExp2 = [[NSExpressionDescription alloc] init];
[subExpLongitude setName:#"subtraction2"];
[subExpLongitude setExpression:[NSExpression expressionForFunction:#"from:subtract:"
arguments:[NSArray arrayWithObjects:
[NSExpression expressionForKeyPath:#"Column4"],
[NSExpression expressionForConstantValue:[NSNumber numberWithDouble:someNumber2]],
nil]]];
[subExp2 setExpressionResultType:NSDoubleAttributeType];
/*Get difference data*/
[fetchRequest setResultType:NSDictionaryResultType];
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:subExp1, subExp2, nil]];
NSArray *listDifference = [context executeFetchRequest:fetchRequest error:nil];
NSLog(#"Subtraction 1: %#", [[listDifference objectAtIndex:0] objectForKey:#"subtraction1"]);
NSLog(#"Subtraction 2: %#", [[listDifference objectAtIndex:0] objectForKey:#"subtraction2"]);
NSMutableDictionary *dictResult;
[dictResult setObject:listData forKey:#"Data"]
[dictResult setObject:listDifference forKey:#"Difference"]
return dictResult;
}
Edit: Get coredata object
This doesn't work.
NSExpressionDescription *expEntity = [[NSExpressionDescription alloc] init];
[expEntity setName:#"TableNameEntity"];
[expEntity setExpression:[NSExpression expressionForKeyPath:#"objectID"]]; //Searches for a column for the name specified
[expEntity setExpressionResultType:NSObjectIDAttributeType];}
Had to change it to below to get it working (Assuming this is the correct way)
NSExpressionDescription *expEntity = [[NSExpressionDescription alloc] init];
[expEntity setName:#"TableNameEntity"];
[expEntity setExpression:[NSExpression expressionForEvaluatedObject]];
[expEntity setExpressionResultType:NSObjectIDAttributeType];
I added expEntity to the setPropertiesToFetch list. Now I get two values in the dictionary.
{
TableNameEntity = "0x5e22120 <x-coredata://1A659A52-9321-4ACD-992B-04F20E7BDCED/TableNameEntity/p1640>";
subtractionValue = "-24.13";
}
When I try to retrieve and access TableNameEntity from the dictionary, the app crashes.
TableNameEntity *tableEntity = (TableNameEntity *)[dict objectForKey:#"TableNameEntity"];
tableEntity.column1 //This is not the exact code. But this operation crashes with error
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_NSObjectID_48_0 column1]: unrecognized selector sent to instance 0x5e22120'
Here if you notice, the value for key TableNameEntity is contained in quotes, so I guess its being returned as a string.
See if you can correct what I've done wrong.
I've tried an alternate to get columns values in the dictionary. Here it is (this works fine). But I guess its not a good approach.
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:subExp1, #"column1", #"column2", ... #"columnN" nil]];
You could make the calculation in a fetch request as follows:
- (NSArray *)myFetchResults
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = [NSEntityDescription entityForName:#"myEntity" inManagedObjectContext:myContext];
request.resultType = NSDictionaryResultType;
NSExpressionDescription *subExDescr = [[NSExpressionDescription alloc] init];
[subExDescr setName:#"subtraction"];
[subExDescr setExpression:[NSExpression expressionForFunction:#"subtract:from:"
arguments:[NSArray arrayWithObjects:
[NSExpression expressionForConstantValue:[NSNumber numberWithInt:someNumber]],
[NSExpression expressionForKeyPath:#"myAttribute"],
nil]]];
[subExDescr setExpressionResultType:NSInteger64AttributeType];
request.propertiesToFetch = [NSArray arrayWithObject:subExDescr, nil];
NSError *err = nil;
NSArray *results = [self.moContext executeFetchRequest:request error:&err];
[request release];
[err release];
return results;
}
The fetch results will be an array of dictionaries. You can access the result for the nth value in the column as follows:
NSArray *results = [self myFetchResults];
NSDictionary *nthDict = [results objectAtIndex:n];
NSInteger nthValue = [nthDict objectForKey:#"subtraction"];
Note that this code is untested. As is, I believe it will operate on all items in the column. If you want to operate only on selected items, you can add a predicate to select the items you want to operate on.
You could also look up the documentation for NSExpression and build all sorts of different operations. The class is a bit dense, but the Apple documentation has some snippets of code that help to understand how to use it. And I hope the above example illustrates how to incorporate it into a fetch request.
EDIT: CORRECTION
The entity, of course, has to be specified in the fetch request. I had initially left that out, but have now corrected the code.
EDIT: RESPONSE TO COMMENT
I'm not sure I understand what you're asking, but this may be it. You can create expression descriptions as follows:
NSExpressionDescription *expLatitude = [[NSExpressionDescription alloc] init];
[expLatitude setName:#"latitude"];
[expLatitude setExpression:[NSExpression expressionForKeyPath:#"Column3"]];
[expLatitude setExpressionResultType:NSDoubleAttributeType];
NSExpressionDescription *expEntity = [[NSExpressionDescription alloc] init];
[expEntity setName:#"TableNameEntity"];
[expEntity setExpression:[NSExpression expressionForKeyPath:#"objectID"]];
[expEntity setExpressionResultType:NSObjectIDAttributeType];}
Then, you add them to the propertiesToFetch array, as two more objects. Each dictionary in the fetch results will now have the latitude, the subtraction resulting from that same latitude, and the corresponding objectID of the entity that contained that latitude. The dictionaries will be ordered in the results array according to your sort descriptors. (I haven't tried the objectID expression, but I think it should work fine.)
Basically, your results are ordered in the exact same order as a traditional fetch request with the same predicate and the same sort descriptors, that is, for a fetch request with the default result type NSManagedObjectResultType.
I hope this answers your question. If not, don't hesitate to ask again. But, I may take a while to answer because it's sleep time for me now.
EDIT: RESPONSE TO 'GET COREDATA OBJECT'
Good catch on finding the correct expression to get the object ID! (Seeing it, the expression I offered for this now looks obviously wrong.)
As to the exception you're getting, it makes sense. The value returned in the fetch results is not the managed object itself, it's only the managed object's ID. To access the managed object, I think the following should work:
NSManagedObjectID *myObjectID = [dict objectForKey:#"TableNameEntity"];
TableNameEntity *tableEntity = (TableNameEntity *)[context objectWithID:myObjectID];
tableEntity.column1
The context above is the NSManagedObjectContext.
However, I think I prefer your final solution. I didn't know you could combine NSExpressionDescriptions with properties in the propertiesToFetch array. Good to know!
More importantly, it may be faster to get all the properties you need in the fetch than to get only the objectID from the fetch and get the properties later. Getting the objectID generally does not fire the fault for the entity. I believe the fault will be fired later, when you access the properties. It will fire once, when accessing the first property, or multiple times, once for each property. (I'm not sure which.) [For an explanation of faulting, see Firing Faults.]
My recommendation is that including all the properties you need in propertiesToFetch is the best approach. (You may try getting the objectID, if you prefer. But, if you find it's slow, you can go back to getting all the properties in the fetch.)
Fetch requests and expressions are poorly documented. You have to play with them a bit to get the syntax right. You seem to be doing very well.

issue with sorting data in UITableview

I have implement a UItable with data sourced via Core Data. The table works fine and presents the data correctly, drills down.. etc.
However, it has the following problem: it presents the content data in a different order every time. I would like it at least to appear consistently or even better alphabetically.
Any ideas on why this might be happening or a specific property or method I should be reviewing in the docuemntation?
Help much appreciated
You need to set an NSSortDescriptor on your NSFetchRequest
NSSortDescriptor *sortDescriptorName = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES selector:#selector(caseInsensitiveCompare:)];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptorName]];
Then create your NSFetchedResultsController with the fetchRequest object.
This would cause your list to appear sorted alphabetically using the property "name" and ignore case while sorting.
You can simply add a sort descriptor to the request. In this example, the data object has a numeric column for "sortOrder", but you could sort on most anything.
- (NSMutableArray *)loadData {
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"NameOfEntity" inManagedObjectContext:context];
[request setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"sortOrder" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
// Handle the error.
}
[request release];
return [mutableFetchResults autorelease];
}
I have not done much with CoreData other than to read about it and review some examples, but I would say this:
It sounds like your data is simply coming out of CoreData unsorted, and the order is in fact not guaranteed UNLESS you provide some additional hint about how you would like it sorted, with say a sort descriptor or something.
Sorry I can't provide a concrete reference, but there has to be a way to both fetch data and specify the order in which it is returned.
Alternatively, you could (behind the scenes) fetch all the table data from CoreData and then sort it yourself, but I think that defeats the purpose of using CoreData in the first place and discards a lot of the functionality of CoreData that is likely more efficient than anything you could write yourself to massage the data.

NSFetchedResultsController custom sort not getting called

I am currently trying to populate a UITableView in my project from Core Data using NSFetchedResultsController. I am using a custom search with a comparator (although I have also tried a selector and had an identical problem):
if (fetchedResultsController != nil) {
return fetchedResultsController;
}
/*
Set up the fetched results controller.
*/
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Object" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"objectName" ascending:YES comparator:^(id s1, id s2) {
NSLog(#"Comparator");
//custom compare here with print statement
}];
NSLog(#"Sort Descriptor Set");
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Object" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:#"firstLetterOfObject" cacheName:#"Objects"];
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
if (![fetchedResultsController performFetch:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return fetchedResultsController;
When I enter this tab, I have logged all over the program and found that the NSFetchedResultsController does not even enter the comparator block when fetching. It instead sorts it with some default sorting method.
If I delete and add an Object with an objectName, however, it then does enter the comparator block and correctly sort the table.
Why does the NSFetchedResultsController not sort using the comparator until the managed object model is changed?
Notes: I have tried also turning off caching, and/or performing a fetch in viewDidLoad:, but it seems that how many times I fetch does not matter, but when. For some reason it only uses my sorting after the object model has been changed.
There are a couple of things I can think of. First, though this may not be your problem, you cannot sort on transient properties. But more likely is that when sorting in a model backed by a SQL store, the comparator gets "compiled" to a SQL query, and not all Objective-C functions are available. In this case, you'd need to sort in memory after the fetch is performed.
EDIT: See this doc, specifically the Fetch Predicates and Sort Descriptors section.
I see the same problem and a way to work around it is to modify an object, save the change then restore it to its original value and save again.
// try to force an update for correct initial sorting bug
NSInteger count = [self.fetchedResultsController.sections count];
if (count > 0) {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:0];
count = [sectionInfo numberOfObjects];
if (count > 0) {
NSManagedObject *obj = [self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
NSString *name = [obj valueForKey:#"name"];
[obj setValue:#"X" forKey:#"name"];
// Save the context.
[self saveContext];
[obj setValue:name forKey:#"name"];
// Save the context.
[self saveContext];
}
}
Sorry, but did you miss the final fetch part to your code snippet?:
NSError *error;
BOOL success = [aFetchedResultsController performFetch:&error];
Don't forget to release the request too:
[fetchRequest release];

NSFetchRequest / Predicate Question

I have two entities: Patient and Job. Patient has a to-many relationship to Job called 'jobs' and Job has a to-one relationship to Patient called 'patient'. Job has attributes called 'dueDate' (Date) and 'completed' (BOOL) and Patient has attributes 'firstName' and 'lastName' (both Strings).
I am trying to create a fetch request / predicate for my NSFetchedResultsController that we grab all Jobs that have not been completed (i.e. completed == NO) and section them by Patient name. Here is my code:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Job" inManagedObjectContext:moc];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(completed == NO)"];
[fetchRequest setPredicate:predicate];
NSSortDescriptor *patientDescriptor = [[NSSortDescriptor alloc] initWithKey:#"patient" ascending:YES];
NSSortDescriptor *dueDateDescriptor = [[NSSortDescriptor alloc] initWithKey:#"dueDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:patientDescriptor, dueDateDescriptor, nil];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:moc sectionNameKeyPath:#"patient" cacheName:#"Jobs"];
Here is my titleForHeaderInSection method:
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:section];
NSString *firstName = [[(Job *)[fetchedResultsController objectAtIndexPath:indexPath] patient] firstName];
NSString *lastName = [[(Job *)[fetchedResultsController objectAtIndexPath:indexPath] patient] lastName];
return [NSString stringWithFormat:#"%# %#", firstName, lastName];
This doesn't seem to work. Am I going about this the wrong way?
How is it not working? It helps to describe what results you are seeing.
You are not adding your sort descriptors to your NSFetchRequest, at least in the sample you provided.
Your sort descriptors are ineffective. It appears that Patient is a relationship so sorting against the relationship will not work. You would want to do a sort like the following:
NSSortDescriptor *lastNameDescriptor = [[NSSortDescriptor alloc] initWithKey:#"patient.lastName" ascending:YES];
NSSortDescriptor *firstNameDescriptor = [[NSSortDescriptor alloc] initWithKey:#"patient.firstName" ascending:YES];
NSSortDescriptor *dueDateDescriptor = [[NSSortDescriptor alloc] initWithKey:#"dueDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: lastNameDescriptor, firstNameDescriptor, dueDateDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[lastNameDescriptor release], lastNameDescriptor = nil;
[firstNameDescriptor release], firstNameDescriptor = nil;
[dueDateDescriptor release], dueDateDescriptor = nil;
You do not need to cast [fetchedResultsController objectAtIndexPath:indexPath] as it returns id.
What are you getting back from the call to [fetchedResultsController objectAtIndexPath:indexPath]? Put a breakpoint here and check the value and make sure you are getting back a NSManagedObject instead of nil. Putting a breakpoint in that method will also confirm that you are getting called.
Your secondKeypathName will not work as mentioned above. You probably want to set it to #"patient.lastName" so that it will match the initial sort I described above.
Your -tableView: titleForHeaderInSection: should be accessing the cache provided by the NSFetchedResultsController instead of assuming that there is going to be a row in the section:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
id sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo name];
}
Finally, if you want the section to truly display the "lastname, firstname" format then you will need to create a non-transient derived value property on your Patient entity that is the fullName so that you can create your cache based on it. This derived value would then need to be updated any time that the first name or last name were changed.
First, you don't seem to attach the sortDescriptors to fetchRequests. This may or may not be connected with the problem.
Second, you can accomplish this in an easier way. Make it like this:
sectionNameKeyPath:#"patient.name"
"name" should be a property or method of the Patient object. An easy way to implement this would be to have a category method on patient:
- (NSString *)name {
return [NSString stringWithFormat:#"%# %#", self.firstName, self.lastName];
}
Actually, you can't accomplish your purpose with something as simple as this, read mzarra's answer for correct answer. NSFetchedResultsController has this critical comment:
If the controller generates sections, the first sort descriptor in the array is used to group the objects into sections; its key must either be the same as sectionNameKeyPath or the relative ordering using its key must match that using sectionNameKeyPath.
But, you cannot sort on the results of a method call, you'd need a property of the object. So, your best bet is probably just have a "name" property on "patient", and use that property for both sorting and sectionNameKeyPath.
In addition to not assigning your sortDescriptors to your fetchRequest, I believe you have a problem with your predicate. Since you are dealing with Core Data, the boolean value for your "completed" attribute is stored in an instance of NSNumber. Something like the predicate below would be better:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"completed = %#", [NSNumber numberWithBool:NO]];