As per the doc when we use custom selector then the objects which are compared against each other should implement the custom selector method and logic to return the result.
You construct instances of NSSortDescriptor by specifying the key path of the property to compare and the order of the sort (ascending or descending).
Optionally, you can also specify a selector to use to perform the comparison, which allows you to specify other comparison selectors, such as localizedStandardCompare: and localizedCaseInsensitiveCompare:. Sorting **raises an exception** if the objects don’t respond to the sort descriptor’s comparison selector.
As explained above we need to implement the sort descriptor’s comparison selector in TaggedDate
Update:
NSSortDescriptor can also be used with comparator instead of expecting the objects to implement the selector.
NSArray* wordsOfVaryingLength = @[@"crow",@"eagle",@"goose"];
NSComparisonResult (^stringLengthCompare)(NSString*, NSString*) = ^NSComparisonResult(NSString *stringOne, NSString *stringTwo) {
NSComparisonResult lengthCompare = NSOrderedSame;
if (stringOne.length < stringTwo.length)
lengthCompare = NSOrderedAscending;
if (stringOne.length > stringTwo.length)
lengthCompare = NSOrderedDescending;
return lengthCompare;
};
NSSortDescriptor *sortByLengthAsc = [NSSortDescriptor sortDescriptorWithKey:nil ascending:YES comparator:stringLengthCompare];
NSLog(@"From shortest word to longest: %@", [wordsOfVaryingLength sortedArrayUsingDescriptors:@[sortByLengthAsc]]);
NSSortDescriptor *sortByLengthDesc = [NSSortDescriptor sortDescriptorWithKey:nil ascending:NO comparator:stringLengthCompare];
NSLog(@"From longest word to shortest: %@", [wordsOfVaryingLength sortedArrayUsingDescriptors:@[sortByLengthDesc]]);
Here stringLengthCompare
will have the comparison logic, similarly for the case sensitive or insensitive use case we need to put that logic here, taken from
let descriptor = NSSortDescriptor(key: "title", ascending: true) { (string1, string2) -> ComparisonResult in
guard let s1 = string1 as? String, let s2 = string2 as? String else {
return ComparisonResult.orderedSame
}
if s1.lowercased() < s2.lowercased() {
return ComparisonResult.orderedAscending
} else if s1.lowercased() == s2.lowercased() {
return ComparisonResult.orderedSame
} else {
return ComparisonResult.orderedDescending
}
}