I'm attempting to replicate the Finder's NSPredicateEditor-based metadata search in an app.
I'd prefer to get the Finder's exact NSPredicateEditor for free, but unless anyone has a better answer for that question it looks like I'm going to have to replicate Finder's search as best as I can.
When working on mirroring the Kind
option, I'm hitting a problem. I start by saving a Finder Spotlight search with all available Kind
options.
When I Get Info
on the resulting saved search folder, the Query is listed as:
(kMDItemContentTypeTree=com.apple.application) &&
(kMDItemContentTypeTree=public.archive) &&
(kMDItemContentTypeTree = public.content) &&
(_kMDItemGroupId = 8) &&
(_kMDItemGroupId = 9) &&
(_kMDItemGroupId = 13) &&
(_kMDItemGroupId = 7) &&
(_kMDItemGroupId = 10) &&
(_kMDItemGroupId = 11) &&
(_kMDItemGroupId = 12) &&
(kMDItemContentTypeTree = public.text) &&
(kMDItemKind = "my_Kind_custom_text*"cdw)
The problem I'm seeing is that the single "Kind" user-displayed text contains multiple key paths that are used in the resulting NSPredicate based on whichever right value is picked.
"Kind" can represent (at least) kMDItemContentTypeTree
, _kMDItemGroupId
, or kMDItemKind
.
When I create an NSPredicateEditorRowTemplate, I pass an array of Left Expressions, Operators, and Right Expressions. The row template is then created containing all possible permutations of Left/Operator/Right.
(Note: I'm creating all NSPredicateEditorRowTemplate
s programatically rather than in Interface Builder).
Finder is not creating all possible permutations of the 3 Left key paths and 12 Right values. It is selectively assigning a certain left key path based on the value picked on the right.
I am localizing the row templates using NSRuleEditor
's formattingDictionary
property, based on the guide found here: http://funwithobjc.tumblr.com/post/1482915398/localizing-nspredicateeditor
I can assign the same localization of "Kind" to two different key path expressions in two different NSPredicateEditorRowTemplate
s.
When I have two row templates localized to "Kind" using the same left key path expression, the following "merge the templates" quote is true and only one "Kind" shows up in the list. The right popup is a union set of all of the vaules from the two templates.
At runtime, NSPredicateEditor will merge the templates together, and the second popup will show a union of all the operators of your date templates. http://www.cocoabuilder.com/archive/cocoa/282859-nspredicateeditorrowtemplate-and-dynamic-templateviews.html
However, when I create two row templates, both localized to "Kind", using different left key path expressions, I instead get two "Kind" rows in my left expression popup. The templates are not merged.
How should I replicate Finder's behavior? I need to somehow merge the left key paths if they have the same localization even if they represent different key paths / expressions, resulting in a single row template with multiple left key paths each with independent sets of right values.
My solution was to have a single source property, then multiple renamed getters that return that property.
Each
kindImage
-type getter is a key path that can be targeted independently in the predicate editor.Despite returning the same value, the predicate editor rows will not merge because they are using different key paths.