1

I'm trying to sort a core data entity by the length of its 'name' property, which is a string.

Location is a NSManagedObject containing a name property (string).

Here's the code:

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:[Location entityName]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"name BEGINSWITH[cd] %@", query]];
[fetchRequest setSortDescriptors:@[
    [NSSortDescriptor sortDescriptorWithKey:@"name.length" ascending:YES]]];
[fetchRequest setFetchLimit:3];
NSArray *locations = [context executeFetchRequest:request error:&error];

I would expect the name.length KVO operator to work but the results are not correctly ordered.

Eg: if the model contains three Location's which name properties are New Orleans, New York and Newcastle, the resulting array with query = "New" should be New York, Newcastle and New Orleans.

Am I missing anything?

Thanks, DAN

DAN
  • 919
  • 1
  • 6
  • 23
  • Its string comparison so this may help you http://stackoverflow.com/questions/24331566/objective-c-sort-an-array-of-strings-containing-numbers – abrar ul haq Oct 21 '15 at 09:40
  • Hi @abrarulhaq, thanks for your answer but unfortunately that solution is exactly what I'm doing, using a KVO operator (in that case the user was using length instead of intValue). – DAN Oct 21 '15 at 09:55
  • Maybe you should post your complete search snippet, along with your results and expectations. – Jody Hagins Oct 21 '15 at 13:30
  • Sure thing! Question updated – DAN Oct 21 '15 at 14:21
  • @DAN - You should always provide specific details for your CoreData questions. There are lots of moving parts, and lots of things that are different depending on how you use it. For example, the important missing part from this question was that you are using SQLite store. Other stores behave differently. – Jody Hagins Oct 21 '15 at 19:11
  • Got it, I had no idea it could depend by the store type. Thank you! – DAN Oct 22 '15 at 10:31

1 Answers1

2

Unfortunately , You can not access .length and other properties of NSString in CoreData ,

I`d suggest to add another property ( @property (nonatomic, retain) NSNumber * nameLength; ) to your ManagedObject class , hold the length of the text and use this property to sort the data, after updating the name, update nameLength as well, if you wan nameLength to be updated automatically, you can use KVO or override setName like this

- (void)setName:(NSString *)newName
{
    [self willChangeValueForKey:@"name"];
    [self setPrimitiveValue:newName forKey:@"name"];
    [self didChangeValueForKey:@"name"];

    NSUinteger length = newName.length;
    // setName will be called when object is created from the store, make sure you only update it when the actual length is changed, 
    if([self.nameLength unsignedIntegerValue] != length) {
        self.nameLength = @(length);
    }
}
ogres
  • 3,660
  • 1
  • 17
  • 16