3

I've got an array of filepaths and I've got a NSPredicateEditor setup in my UI where the user can combine a NSPredicate to find a file. He should be able to filter by name, type, size and date.

There are several problems I have now:

  • I can only get one predicate object from the editor. When I use "predicateForRow:" it returns (null)
  • If the user wants to filter the file by name AND size or date, I can't just use this predicate on my array anymore because those information are not contained in it

Can I split up a predicate into different predicates without converting it into a NSString object, then search for every @" OR " | @" AND " and seperating the components into an array and then converting every NSString into a new predicate?


In the NSPredicateEditor settings I've some options for the "left Expression": Keypaths, Constant Values, Strings, Integer Numbers, Floating Point Numbers and Dates. I want to display a dropdown menu to the user with "name", "type", "date", "size". But then the generated predicate automatically looks like this:

"name" MATCHES[c] "nameTest" OR "type" MATCHES[c] "jpg" OR size == 100

Because the array is filled with strings, a search for "name", "type" etc. and those strings do not respond to @"myString"*.name*m the filter always returns 0 objects. Is there a way to show the Name, Type, Size and Date in the Menu, but write "self" into the predicate without doing it by hand?

I've already searched in the official Apple tutorials, on Stackoverflow, Google, and even Youtube to find a clue. This problem troubles me for almost one week now. Thanks for you time! If you need more information please let me know!

Git.Coach
  • 3,032
  • 2
  • 37
  • 54

1 Answers1

3

You have come to the right place! :)

I can only get one predicate object from the editor.

Correct. It is an NSPredicateEditor, not an NSPredicatesEditor. ;)

When I use "predicateForRow:" it returns (null)

I'm not sure I would use that method. My general rule of thumb is to largely ignore that NSPredicateEditor is a subclass of NSRuleEditor, mainly because it's such a highly specialized subclass that many of the superclass methods don't make that much sense on a predicate editor (like all the stuff about criteria, row selection, etc). It's possible that they're somehow relevant, but if they are, I haven't figured out how yet.

To get the predicate from the editor, you do:

NSPredicate *predicate = [myPredicateEditor objectValue];

If the user wants to filter the file by name AND size or date

You mean (name = [something]) AND (size = [something] OR date = [something])?

If so, NSPredicateEditor can do that if you've set the nesting mode to "Compound".

I can't just use this predicate on my array anymore because those information are not contained in it

What information do you need?

Can I split up a predicate into different predicates without converting it into a NSString object, then search for every @" OR " | @" AND " and seperating the components into an array and then converting every NSString into a new predicate?

Yes, but that is a BAD idea. It's bad because NSPredicate already contains all the information you need, and converting it to a different format and doing string manipulations just isn't necessary and can potentially lead to complications (like if someone can type in a value for "name", what happens if they type in " OR "?).

I'm having a hard time trying to figure out what it is you're trying to do. It sounds like you have an array of NSString objects that you want to filter based on a predicate that the user creates? If so, then what do these name, date, and size key paths mean? What are you trying to do?

Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • Hi Dave! Thank you very much for your long answer and the helpful tipps you provided! I've already nested the predicate via compound, the problem is as following: My dataController owns an array of custom objects. Each of those objects contains a path from where I get all the subPaths to search for files there. So I have got an array of subPaths and I want to search for one or more different specifications the user selects via the Pred.Edit.. But this arrayOfSubpaths does not contain any of those other information. To get access I have to change the left expr. to "self" by hand.What can I do? – Git.Coach Jul 08 '12 at 00:57
  • To make it a bit clearer: If my predicate just filters for name, it's almost fine. I've to change "name" to "self" and then it identifies the correct path from the subPaths array. But if the user wants to sort by multiple values, they are not contained in the subPaths array and I would have to create a different array with new data and filter again. But then the predicate would not find anything, because the names are not contained in the array. I try to avoid creating a customobject with 4 attributes "just in case". Do you understand my problem a bit better now? – Git.Coach Jul 08 '12 at 01:48
  • 1
    @Tom predicates work best when evaluated against homogeneous objects (i.e., they're all the same time). I think that if you're avoiding creating a simple model object just because it's only 4 attributes, that that may be potentially unwise. – Dave DeLong Jul 08 '12 at 04:01
  • Okay, then I'll do it! If I encounter anymore trouble, I'll ask here again. Thanks for your time! – Git.Coach Jul 08 '12 at 11:21
  • Now it's working. Almost... :) In the PredicateEditor the left expression of each row is set to "key path". I have to put the attributes name in it, but then it looks bad in the PredEditor. Is there a way to display a different String to the user than the attribute we're searching for? Like: "Size in MB", but search for "fileSize"? – Git.Coach Jul 08 '12 at 14:53
  • 1
    @Tom yep, you can do that. Check out [the posts here](http://funwithobjc.tumblr.com) on Localizing NSPredicateEditor. – Dave DeLong Jul 17 '12 at 17:11