Question

I'm setting up an NSFetchedResultsController. My entity has an attribute that is called "hasRight" (bool) and another attribute called "sortOrder" (int). If "hasRight" of an entry is true, there is also a sortOrder, which is an integer, available. If on the other hand "hasRight" is false, the sortOrder is always 0 (zero). Currently my code looks like this:

- (NSFetchedResultsController *)setupFetchedResultsController:(JournalCategory*) journalCategory
{
    NSManagedObjectContext *managedObjectContext = [[ConfigurationManager sharedInstance] mainManagedObjectContext];

    NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
    [fetch setEntity:[NSEntityDescription entityForName:@"Journal" inManagedObjectContext:managedObjectContext]];

    NSSortDescriptor *sortDescriptorHasRight = [[NSSortDescriptor alloc] initWithKey:@"hasRight" ascending:NO];
    NSSortDescriptor *sortDescriptorSortOrder = [[NSSortDescriptor alloc] initWithKey:@"sortOrder" ascending:YES];
    [fetch setSortDescriptors:[NSArray sortDescriptorHasRight, sortDescriptorSortOrder, nil]];

    predicate = [NSPredicate predicateWithFormat:@"journalCategory == %@", journalCategory];
    [fetch setPredicate:predicate];

    return [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
}

This code sorts my entries according to "hasRight", therefore entries with that flag set to true are displayed before entries with "hasRight" set to false. Afterwards, the entries are sorted according to the attribute "sortOrder". This works fine for all entries with "hasRight" set to true, because each entry has a unique "sortOrder".

The problem is that all entries with "hasRight" set to false have a "sortOrder" of 0. I'm displaying the data of this Fetch in a UICollectionView. What happens is that each time the data in the UICollectionView is reloaded, the UICollectionView fetches above NSFetchedResultsController again and all entries with "hasRight" false are ordered randomly because all entries have the same value (0) for "sortOrder". Therefore each time theUICollectionView is reloaded, all cells with "hasRight" set to false rearrange in a random order.

What I'd like to do is to apply the second NSSortDescriptor (sortDescriptorSortOrder) only to all entries that have "hasRight" set to true. Is that even possible with an NSFetchedResultsController and if yes, can anyone tell me how?

Was it helpful?

Solution

What you want is not possible. But even if it would be possible it would not solve your problem. Because without the 2nd sortDescriptor the objects with hasRight==NO are still not sorted, and will be returned in a random fashion.

You need a third sortDescriptor, make that title or creationDate or any attribute that is unique to an object.
The objects with hasRight=YES won't be affected by the third sortDescriptor because the second sortDescriptor (sortOrder) is already unique for each object.

If you don't have another unique attribute you can use sortOrder for hasRight=NO objects as well. Because your first sortDescriptor is hasRight all objects with hasRight=NO will still come later.

For example this is the resulting order if you sort by hasRight and sortOrder

hasRight | sortOrder
YES      | 1
YES      | 2
YES      | 3
NO       | 1
NO       | 2
NO       | 3
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top