views:

59

answers:

2

I'm trying to create a list of people sorted in a tableView of sections with the first letter as the title for each section - a la Address Book. I've got it all working, though there is a bit of an issue with the sort order. Here is the way I'm doing it now:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Contact" inManagedObjectContext:context]];

NSSortDescriptor *fullName = [[NSSortDescriptor alloc] initWithKey:@"fullName" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:fullName, nil];
[request setSortDescriptors:sortDescriptors];
[fullName release];
[sortDescriptors release];

NSError *error = nil;
[resultController release];
resultController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:@"firstLetter" cacheName:nil];
[resultController performFetch:&error];
[request release];

fullName is a standard property, and firstLetter is a transient property which returns - as you'd expect - the first letter of the fullName. 95% of the time, this works perfectly.

The problem is the result controller expects these two "lists" (the sorted fullName list and the sorted firstLetter list) to match exactly. If I have 2 contacts like John and Jack, my fullName list would sort these as Jack, John every time but my firstLetter list might sort them as John, Jack sometimes as it's only sorting by the first letter and leaving the rest to chance. When these lists don't match up, I get a blank tableView with 0 items in it.

I'm not really sure how I should go about fixing this issue, but it's very frustrating. Has anyone else run into this? What did you guys find out?

A: 

I have not played with the section index too much but one thought would be to add the firstLetter sort as the first sort on your NSFetchRequest and add the fullName sort as a second sort.

If that doesn't work it would be great if you could post a sample project with the error so that we can play with it. If it turns out to be an Apple bug that same sample project can be used to submit the radar. If its not you are more likely to get someone to help solve it when they don't have to create the same project and try to rediscover the bug.

Plus there is always the off chance in the sample project that you stumble upon the answer. Happens to me all the time :)

UPDATE

I prefer Gerry3's answer.

Marcus S. Zarra
Thanks, I'll try to create a project which does this. The problem is this issue is very rare, but every once in a while I've seen it and I've gotten a couple emails from customers saying their entire list went blank - which is from this problem. It would be hard to replicate reliably enough to debug directly, but when it does happen it's a serious problem.
Cory Imdieke
+3  A: 

I am confused by what you mean by "first letter list".

You should not be creating such a list. You only implement the getter for the transient "firstLetter" property and use the fetched results controller's boiler-plate methods to implement the table view methods.

See this answer to How to use the first character as a section name for details.

gerry3
Thanks for the response. I'm not actually creating a list, core data is creating a list internally. The link you gave me is exactly how I'm doing everything, using a transient property to feed me the first letter of the object. Core Data maintains 2 lists internally, the main sort list and the section list which it uses to calculate which objects belong in which section. Those two lists must be sorted the same, and if they aren't we run into problems - like the one I'm having.
Cory Imdieke