objective-ccocoanspredicatenspredicateeditornsexpression

NSPredicateEditor & NSExpression - Can the display be different than the value for the predicate?


I have a predicate editor, which the template was generate via the following:

    NSArray * test = [NSArray arrayWithObjects:
                      [NSExpression expressionForKeyPath: @"Abc"],
                      [NSExpression expressionForKeyPath: @"Def"],
                      nil];


    NSPredicateEditorRowTemplate * template = [[NSPredicateEditorRowTemplate alloc] initWithLeftExpressions: test
                                   rightExpressionAttributeType: NSStringAttributeType
                                                       modifier: NSDirectPredicateModifier
                                                      operators: [NSArray arrayWithObject:
                                                                 [NSNumber numberWithUnsignedInteger:NSContainsPredicateOperatorType]]
                                                        options:(NSCaseInsensitivePredicateOption|NSDiacriticInsensitivePredicateOption)];

So if I fill in a predicate editor like this: Predicate Editor

When I log out the generated predicate I get:

Abc CONTAINS[cd] "abc" OR Def CONTAINS[cd] "def"

What I'm wondering is if I can somehow have the predicate editors template display be different than the value that gets set in the generated predicate.

EX: I want the output predicate to have:

Field1 CONTAINS[cd] "abc" OR Field2 CONTAINS[cd] "def"

Even though the editor still displays abc and def as the fields. Is this possible?


Solution

  • Yes, you can do this.

    You want the array of left expressions to be the actual keyPaths in the final predicate. In your case, "Field1" and "Field2".

    As for making a different value appear in the popup, here's where a mind-bending concept comes in:

    You're going to localize your predicate editor into English.

    There are two ways you could do this.

    1. With a .strings file
    2. With an NSDictionary

    With a .strings file

    In your source, you would include the following in a comment:

    // NSLocalizedStringFromTable(@"%[Field1,Field2]@ %[contains]@ %@", @"PredicateEditor", @"")
    

    When you run genstrings on your source code, this will generate a PredicateEditor.strings file with the following entries:

    "%[Field1]@ %[contains]@ %@" = "%[Field1]@ %[contains]@ %@";
    "%[Field2]@ %[contains]@ %@" = "%[Field2]@ %[contains]@ %@";
    

    You would change the values to be:

    "%[Field1]@ %[contains]@ %@" = "%[Abc]@ %[contains]@ %@";
    "%[Field2]@ %[contains]@ %@" = "%[Def]@ %[contains]@ %@";
    

    Then, when you create your NSPredicateEditor, you would set the formattingStringsFileName property to "PredicateEditor", and the editor will take care of the rest.

    With an NSDictionary

    This would follow the same fundamental concepts as the .strings option, except that you would essentially do:

    NSDictionary *formatting = @{
      @"%[Field1]@ %[contains]@ %@" : @"%[Abc]@ %[contains]@ %@",
      @"%[Field2]@ %[contains]@ %@" : @"%[Def]@ %[contains]@ %@"
    }
    [myPredicateEditor setFormattingDictionary:formatting];
    

    That's all you have to do.

    I blogged about this a long time ago, and that has more information that you might find useful.