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?
Best Answer
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: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 aNSManagedObject
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 theNSFetchedResultsController
instead of assuming that there is going to be a row in the section: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 thefullName
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.