1

I'm trying to execute a fetch request on an entity Folders, and I want a folder named xyz to be the last object when sorted.

  NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription 
                                   entityForName:@"Folder" inManagedObjectContext:appDelegate.managedObjectContext];

    [fetchRequest setEntity:entity];

    NSSortDescriptor *lastDescriptor =
    [[[NSSortDescriptor alloc] initWithKey:@"folderName" ascending:YES comparator:^NSComparisonResult(NSString* name1, NSString* name2) {
        NSLog(@"descriptor");
        if ([name1 isEqualToString:@"xyz"]) {
            return NSOrderedAscending;
        }
        if ([name2 isEqualToString:@"xyz"]) {
            return NSOrderedDescending;
        }

        return [name1 compare:name2];
    }] autorelease];  


    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:lastDescriptor]];
    [fetchRequest setFetchBatchSize:5];

    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
    self.fetchedResultsController = theFetchedResultsController;
    self.fetchedResultsController.delegate=self;   

    [fetchRequest release];
    [theFetchedResultsController release];

    NSError *error;
    if (![[self fetchedResultsController] performFetch:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }

But none of the NSLog statements are being called. Are they supposed to? And the folder xyz does not appear last, but everything ends up being sorted in alphabetical order. Am I doing something wrong?

Edit: Posted full code

Snowman
  • 31,411
  • 46
  • 180
  • 303
  • mine maybe a dumb question, but are are you actually executing the fetch? this only sets up the sort. – danh Apr 11 '12 at 15:40
  • Well ya I do get results, they're just not sorted properly. I end up getting results in alphabetical order, even though this is the only sort descriptor I'm calling.. – Snowman Apr 11 '12 at 15:42
  • Are the NSLog statements supposed to be showing up? – Snowman Apr 11 '12 at 15:45
  • yes. if the sort is using that sort descriptor, you will see NSLogs. – danh Apr 11 '12 at 15:49
  • can you try this: make up a dummy array containing dictionaries that have the key @"folderName". then run sortedArrayUsingDescriptors: on that. it's the same logic that you have, but takes the most complex component (core data) out of the mix. debug that until it works. then you can turn this loose on your MOC. – danh Apr 11 '12 at 15:53
  • I tried your sort and it works fine (NSLogs and all). I think your problem is elsewhere. Probably in the delegate setup. Try this: [appDelegate.managedObjectContext executeFetchRequest:fetchRequest error:&error]; I think you're going to see a good sorted array. – danh Apr 11 '12 at 16:07
  • need code formatting to express myself... see answer below – danh Apr 11 '12 at 16:10
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/9971/discussion-between-danh-and-mohabitar) – danh Apr 11 '12 at 16:24

1 Answers1

1

This code (your code) works:

- (void)sortMe {

    NSDictionary *d0 = [NSDictionary dictionaryWithObject:@"efg" forKey:@"folderName"];
    NSDictionary *d1 = [NSDictionary dictionaryWithObject:@"xyz" forKey:@"folderName"];
    NSDictionary *d2 = [NSDictionary dictionaryWithObject:@"abc" forKey:@"folderName"];
    NSDictionary *d3 = [NSDictionary dictionaryWithObject:@"def" forKey:@"folderName"];
    NSArray *testMe = [NSArray arrayWithObjects:d0, d1, d2, d3, nil];

    NSSortDescriptor *lastDescriptor =
    [[NSSortDescriptor alloc] initWithKey:@"folderName" ascending:YES comparator:^NSComparisonResult(NSString* name1, NSString* name2) {
        NSLog(@"descriptor");
        if ([name1 isEqualToString:@"xyz"]) {
            return NSOrderedAscending;
        }
        if ([name2 isEqualToString:@"xyz"]) {
            return NSOrderedDescending;
        }

        return [name1 compare:name2];
    }];

    NSArray *sorted = [testMe sortedArrayUsingDescriptors:[NSArray arrayWithObject:lastDescriptor]];
    for (NSDictionary *d in sorted) {
        NSLog(@"value=%@", [d valueForKey:@"folderName"]);
    }
}

I predict this code will work, too:

NSError *error;
NSArray *result =  [appDelegate.managedObjectContext executeFetchRequest:fetchRequest error:&error];
// log the array

I think the problem is in the NSFetchedResultsController delegate setup, elsewhere in the code.

danh
  • 62,181
  • 10
  • 95
  • 136
  • 1
    Calling this returned an unsorted array:NSArray *result = [appDelegate.managedObjectContext executeFetchRequest:fetchRequest error:&error]; But if I sort that array after with the same sort descriptor, it works. It's something to do with the fetch requests not applying the sort descriptor. Where should I begin to look to fix this? – Snowman Apr 11 '12 at 16:15