NSPredicateEditorRowTemplate and CoreData

986 views Asked by At

I am trying to generate predicate editor templates for my Core Data entities. In my code I have the following:

 NSEntityDescription *descrip = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:managedObjectContext];
   NSArray *templates = [NSPredicateEditorRowTemplate templatesWithAttributeKeyPaths:[NSArray arrayWithObjects:@"name", @"age", nil] inEntityDescription:descrip];

   [ibPredicateEditor setRowTemplates: templates];

   NSPredicate *p = [NSPredicate predicateWithFormat:@"name like 'John'"];

   [ibPredicateEditor setObjectValue:p];

Printing out the contents of the templates array gives me the following:

CFArray 0x1002d7400 [0x7fff70ff5f20] {type = immutable, count = 2, values = ( 0 : NSPredicateEditorRowTemplate 0x10025c090: [name] [99, 4, 5, 8, 9] NSStringAttributeType 1 : NSPredicateEditorRowTemplate 0x1002d2dc0: [age] [4, 5, 0, 2, 1, 3] NSInteger16AttributeType )}

When this code executes I get the following on the console:

Warning - unable to find template matching predicate name LIKE "John"

The interface for doing this looks extremely straight forward, so I can't seem to figure out what I am doing wrong. Any help would be greatly appreciated!

EDIT

My original issue was that I was using the LIKE operator when my templates did not support it. However I am confused about why I get a similar warning when passing in a compound predicate into the editor.

NSPredicate *p = [NSPredicate predicateWithFormat:@"name CONTAINS 'John'"];
NSPredicate *p2 = [NSPredicate predicateWithFormat:@"name CONTAINS 'Jo'"];
NSPredicate *final = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:p, p2, nil]];
[ibPredicateEditor setObjectValue: final];

OR

NSPredicate *final = [NSCompoundPredicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:p, p2, nil]];
[ibPredicateEditor setObjectValue: final];

Both of these produce similar warnings as my initial issue. However, I find it odd that I can use a single predicate and build a compound and predicate, but I can't pass a prebuilt compound and predicate into the editor.

2

There are 2 answers

0
Ashley Clark On BEST ANSWER

The default templates supplied by NSPredicateEditorRowTemplate for NSString key-paths do not support comparisons with the LIKE operator.

In the templates you generated there is a list of the operators it does support:

NSPredicateEditorRowTemplate 0x10025c090: [name] [99, 4, 5, 8, 9] NSStringAttributeType

[99, 4, 5, 8, 9] indicates that the name NSString attribute supports:

4 – Equal To
5 – Not Equal To
8 – Begins With
9 – Ends With
99 – Contains

(found in NSComparisonPredicate.h)

CONTAINS is similar to LIKE without % and _ substitutions. If you require that you can always initialize your own template array.

The syntax is a bit verbose.

NSExpression *nameExpression = [NSExpression expressionForKeyPath:@"name"];
NSArray *operators = [NSArray arrayWithObjects:
      [NSNumber numberWithInt: NSEqualToPredicateOperatorType],
      [NSNumber numberWithInt:NSNotEqualToPredicateOperatorType],
      [NSNumber numberWithInt:NSLikePredicateOperatorType],
      [NSNumber numberWithInt:NSBeginsWithPredicateOperatorType],
      [NSNumber numberWithInt:NSEndsWithPredicateOperatorType],
      [NSNumber numberWithInt:NSContainsPredicateOperatorType],
      nil];

NSUInteger options = (NSCaseInsensitivePredicateOption |
                      NSDiacriticInsensitivePredicateOption);

NSPredicateEditorRowTemplate *template = [[NSPredicateEditorRowTemplate alloc]
      initWithLeftExpressions:[NSArray arrayWithObject:nameExpression]
      rightExpressionAttributeType:NSStringAttributeType
      modifier:NSDirectPredicateModifier
      operators:operators
      options:options];
1
gerry3 On

It may be a problem with the LIKE operator. This code logs no warning:

NSPredicate *p;
p = [NSPredicate predicateWithFormat:@"name == 'John'"];
[ibPredicateEditor setObjectValue:p];

p = [NSPredicate predicateWithFormat:@"age > 18"];
[ibPredicateEditor setObjectValue:p];