Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 5930557
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 22, 20262026-05-22T14:34:16+00:00 2026-05-22T14:34:16+00:00

I’m having some issues with a mixed, indexed, searchable results set from an NSFetchedResults

  • 0

I’m having some issues with a mixed, indexed, searchable results set from an NSFetchedResults controller. I have it set up to store an indexed A-Z first initial for an entity, and then want it to display numeric first initials (i.e. # as the UILocalizedIndexCollation would do).

I have already written the code that saves a “firstInitial” attribute of an Artist object as NSString @”#” if the full name started with a number, and I seem to have gotten the code half working in my UITableViewController with a customised sort descriptor. The problem is that it only works until I quit/relaunch the app.

At this point, the # section from the fetched results appears at the top. It will stay there until I force a data change (add/remove a managed object) and then search for an entry, and clear the search (using a searchDisplayController). At this point the section re-ordering will kick in and the # section will be moved to the bottom…

I’m obviously missing something/have been staring at the same code for too long. Alternatively, there’s a much easier way of doing it which I’m not aware of/can’t find on Google!

Any help would be appreciated!

Thanks

Sean

The relevant code from my UITableViewController is below.

- (void)viewDidLoad
{
    // ----------------------------------
    // Various other view set up things in here....
    // ...
    // ...
    // ----------------------------------

    NSError *error;
    if (![[self artistResultsController] performFetch:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Failed to fetch artists: %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }

}
- (NSFetchedResultsController *)artistResultsController {

if (_artistResultsController != nil) {
    return _artistResultsController;
}

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription 
                               entityForName:@"Artist" inManagedObjectContext:_context];
[fetchRequest setEntity:entity];

NSSortDescriptor *initialSort = [[NSSortDescriptor alloc] 
                          initWithKey:@"firstInitial" 
                          ascending:YES 
                          comparator:^(id obj1, id obj2) {
                              // Various number conditions for comparison - if it's a # initial, then it's a number
                              if (![obj1 isEqualToString:@"#"] && [obj2 isEqualToString:@"#"]) return NSOrderedAscending;
                              else if ([obj1 isEqualToString:@"#"] && ![obj2 isEqualToString:@"#"]) return NSOrderedDescending;
                              if ([obj1 isEqualToString:@"#"] && [obj2 isEqualToString:@"#"]) return NSOrderedSame;
                              // Else it's a string - compare it by localized region
                              return [obj1 localizedCaseInsensitiveCompare:obj2];
                          }];

NSSortDescriptor *nameSort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];

[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:initialSort, nameSort, nil]];

[fetchRequest setFetchBatchSize:20];

NSFetchedResultsController *theFetchedResultsController = 
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                    managedObjectContext:_context 
                                      sectionNameKeyPath:@"firstInitial" 
                                               cacheName:nil];
self.artistResultsController = theFetchedResultsController;
_artistResultsController.delegate = self;

[nameSort release];
[initialSort release];
[fetchRequest release];
[_artistResultsController release];

return _artistResultsController;}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return nil;
    } else {
        return [[[_artistResultsController sections] objectAtIndex:section] name];
    }
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return nil;
    } else {
        return [[NSArray arrayWithObject:UITableViewIndexSearch] arrayByAddingObjectsFromArray:
                [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles]];

    }
}

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return 0;
    } else {
        if (title == UITableViewIndexSearch) {
            [tableView scrollRectToVisible:self.searchDisplayController.searchBar.frame animated:NO];
            return -1;
        } 
        else {
            for (int i = [[_artistResultsController sections] count] -1; i >=0; i--) {
                NSComparisonResult cr = 
                [title localizedCaseInsensitiveCompare:
                 [[[_artistResultsController sections] objectAtIndex:i] indexTitle]];
                if (cr == NSOrderedSame || cr == NSOrderedDescending) {
                    return i;
                }
            }
            return 0;
        }
    }
}

EDIT: Forgot to mention – my search filter is using a predicate on the fetchedResults controller, so this causes a new fetch request, like so

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
    NSFetchRequest *aRequest = [_artistResultsController fetchRequest];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH[cd] %@", searchText];
    // set predicate to the request 
    [aRequest setPredicate:predicate];
    // save changes
    NSError *error = nil;
    if (![_artistResultsController performFetch:&error]) {
        NSLog(@"Failed to filter artists: %@, %@", error, [error userInfo]);
        abort();
    }  
} 
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-22T14:34:17+00:00Added an answer on May 22, 2026 at 2:34 pm

    I ended up going about fixing this a different way.

    SortDescriptors seem to have issues with running a custom sort when you are also using CoreData with SQLite for your backend storage. I tried a few things; NSString categories with a new comparison method, the compare block as listed above, and refreshing the table multiple times to try and force an update with the sort criterion.

    In the end, I couldn’t force the sort descriptor to do an initial sort, so I changed the implementation. I set the firstInitial attribute for artists whose names began with numerics to ‘zzzz’. This means that CoreData will sort this correctly (numerics last) off the bat.

    After doing this, I then hardcoded my titleForHeaderInSection method to return # for the title if appropriate, as below:

    if ([[[[_artistResultsController sections] objectAtIndex:section] indexTitle] isEqualToString:@"zzzz"]) return [NSString stringWithString:@"#"];
    return [[[_artistResultsController sections] objectAtIndex:section] indexTitle];
    

    Essentially this means it’s sorting numbers into a ‘zzzz’ grouping, which should be last, and I’m just ignoring that title and saying the title is # instead.

    Not sure if there’s a better way to do this, but it keeps all of the sorting inside CoreData, which is probably more efficient/scalable in the long run.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have just tried to save a simple *.rtf file with some websites and
For some reason, after submitting a string like this Jack’s Spindle from a text
I have a string like this: La Torre Eiffel paragonata all’Everest What PHP function
We're building an app, our first using Rails 3, and we're having to build
I have a text area in my form which accepts all possible characters from
I have a bunch of posts stored in text files formatted in yaml/textile (from
I have some data like this: 1 2 3 4 5 9 2 6
I have a jquery bug and I've been looking for hours now, I can't
this is what i have right now Drawing an RSS feed into the php,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.