Advanced use of NSSearchField's predicate binding

Discussion in 'Mac Programming' started by Nutter, May 19, 2007.

  1. Nutter macrumors 6502

    Joined:
    Mar 31, 2005
    Location:
    London, England
    #1
    In my app I'm presenting to the user the contents of their iTunes library. Each track is represented by a custom object in an array, controlled by an NSArrayController, which is displayed in an NSTableView.

    In my first implementation of searching I'm binding the predicate binding of an NSSearchField to my array controller, with this predicate format:
    (name contains[cd] $value) OR (album contains[cd] $value) OR (albumArtist contains[cd] $value) OR (artist contains[cd] $value) OR (composer contains[cd] $value) OR (genre contains[cd] $value)

    I'm chuffed (to say the least!) with how well this works, considering it requires no code at all. However, it isn't quite as flexible as iTunes' search. iTunes seems to break up the search query and perform it word by word, matching each word in any of the track's properties. For example, if you type "jackson bad" into the search field, you will get the song "Bad" by the artist "Michael Jackson".

    I can't work out how to do this with my predicate binding, since $value represents the entire search string and there seems to be no way to break it down. Is my only option to perform the searching manually in code? This would seem to be a waste of a good binding!
     
  2. Eraserhead macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #2
    Performing the search in code isn't actually a big deal, you just create an action which is linked from the search field. Also bindings aren't always the best way of doing things, though for basic functionality they are simpler.
     
  3. Nutter thread starter macrumors 6502

    Joined:
    Mar 31, 2005
    Location:
    London, England
    #3
    It's not the binding I'm worried about per se, it's being able to set a predicate to filter the NSArrayController in the way I want. If I can't do that I'll have to subclass the array controller and implement some kind of custom filtering behaviour. (I saw an example for that somewhere, not the end of the world I know, but it is a lot less elegant.)

    Just wondering if anybody has come across this kind of situation before.
     
  4. Eraserhead macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #4
    You can do that in code too ;). You just have to have the NSArrayController as an IBOutlet in the header file.
     
  5. Nutter thread starter macrumors 6502

    Joined:
    Mar 31, 2005
    Location:
    London, England
    #5
    Sure! But the point is that I don't know how to set up a predicate that will do what I want. I still have to come up with a format string for the predicate, even if I set it in code.
     
  6. Eraserhead macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #6
    You get what they've typed in into a string using [sender stringValue] or [searchBox stringValue] if you have attached an IBOutlet called searchBox to the search field.

    Go away, do some prints using NSLog and read a decent book on Cocoa, such as Aaron Hillegass's one, read the relevant documentation for NSString, NSPredicate and NSSearchField, and then you'll be able to figure it out.
     
  7. Nutter thread starter macrumors 6502

    Joined:
    Mar 31, 2005
    Location:
    London, England
    #7
    ... You're still missing the point. Perhaps I didn't phrase my original query very well. The problem is not that I don't know how to set up a predicate. The problem is that I want to use a more subtle form of filtering that splits the search string up into words. I want to search for the presence of each word, rather than the whole phrase typed in the search box as a whole. A bit like a google search: unless you include quotes around a phrase, google searches for each word individually and not necessarily in the order that you type them.

    I'm prepared and able to do this manually one way or another, and indeed I think I can see a way to do it with a bit of string processing and a rather intricately crafted NSPredicate format. I was just wondering if there was some predicate format syntax I was missing that would make this easier.
     
  8. Eraserhead macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #8
    I see what you are saying, sorry if I was a bit rude :eek:.

    You can split the string up using the componentsSeparatedByString: method in NSString.
     
  9. caveman_uk Guest

    caveman_uk

    Joined:
    Feb 17, 2003
    Location:
    Hitchin, Herts, UK
    #9
    Not as far as I know....I had to roll my own using componentsSeparatedByString...
     
  10. Nutter thread starter macrumors 6502

    Joined:
    Mar 31, 2005
    Location:
    London, England

Share This Page