unsupported NSSortDescriptor (comparator blocks are not supported)
Asked Answered
D

2

12

In fetchedResultsController while setting the NSSortDescriptor iam getting this error unsupported NSSortDescriptor (comparator blocks are not supported).

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

//Below code is not working and causing error. sorting use the hours&seconds part of the time attribute  

NSSortDescriptor *sort = [[NSSortDescriptor alloc]
                          initWithKey:@"time" ascending:YES comparator:^NSComparisonResult(id obj1, id obj2) {

                                  NSCalendar *calendar = [NSCalendar currentCalendar];
                                  NSDateComponents *components1 = [calendar components:(NSHourCalendarUnit|NSMinuteCalendarUnit) fromDate:obj1];
                                  NSDateComponents *components2 = [calendar components:(NSHourCalendarUnit|NSMinuteCalendarUnit) fromDate:obj2];
                                  NSDate *date1 = [calendar dateFromComponents:components1];
                                  NSDate *date2 = [calendar dateFromComponents:components2];


                                  return [date1 compare:date2];

                          }];
Disarmament answered 18/2, 2013 at 14:31 Comment(0)
I
14

You can't use sort descriptors with comparator blocks everywhere - for instance not with Core Data fetches.

They work fine when you filter normal arrays, though.

Apart from that - was there a question in there that I overlooked?

Iphigeniah answered 18/2, 2013 at 14:34 Comment(4)
What I can do for getting the above result?Disarmament
@Anil Well, a simple way could be to extract all your data into an array, then sort that array with the sort descriptor from your code.Iphigeniah
I did like that. Sorting externally after fetching. But the problem i s am using controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath for updating the table view. While performing deletion some other row at indexpath is getting deleted.Disarmament
I think perhaps the overlooked part is why the nonsensical decision (on Apple's part) to not allow comparator blocks to work with Core Data fetches in the first place. And also how to work around it within Core Data fetches.Submergible
P
8

As Monolo said, you can't use comparators block with Core Data. However, you can use:

[NSSortDescriptor sortDescriptorWithKey:(NSString *) ascending:(BOOL) selector:(SEL)]

You'll need to extend your model, if you aren't using a standard selector.

For example, I just needed to order strings "a la Finder" (i.e. 1,2,9,10, and not 1,10,2,9) and I used

request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:myEntity ascending:NO selector:@selector(localizedStandardCompare:)]];

Take a look to the NSSortDescriptor Class Reference by Apple

Happy coding :)

Pollock answered 14/7, 2014 at 20:42 Comment(8)
it does not work in Core Data. The sorting happens in the SQLite backend. localizedStandardCompare works, probably because it is a selector of NSString and apple did something to translate how it compares.Bugbee
Sorry, I don't understand your comment: I started my answer with "you can't use comparators block with Core Data", I guess it's pretty obvious that it doesn't work in Core Data...Pollock
I mean the selector does not work on core data either. like if we have a @selector(fancyCompare:) on model. It does not work with Core Data.Bugbee
I don't know about other selectors, but I can assure you @selector(localizedStandardCompare:) it does work: I'm using it in a TableViewController, applying it to a NSFetchRequest, as showed in my answer (in iOS7 and iOS8, at least).Pollock
yes, I implemented my own - (NSComparisonResult)typeCompare:(NSString*)obj2 but I get unsupported NSSortDescriptor selector: typeCompare: in core dataSelinski
Digging up this zombie since I found the comments unhelpful- you have to use one of the built in comparator selectors. See https://mcmap.net/q/1017748/-custom-selector-for-nssortdescriptor-and-nsfetchedresultscontroller.Jo
+1 — was looking into blocks to fix the [1, 10, 2] sorting issue. localizedStandardCompare: works instead!Aspic
I extended the model with the @objc func localizedStandardCompare(_ string: String) -> ComparisonResultfunction but it is not called. I found information that it should be an extension of the value type. In my case it is NSString. So I did this for an NSString with the function name customCompare, it was called but crashed with the error "unsupported NSSortDescriptor selector: customCompare:". So it doesn't work the same way as comparator.Bandler

© 2022 - 2024 — McMap. All rights reserved.