Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Nutter

macrumors 6502
Original poster
Mar 31, 2005
432
0
London, England
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!
 

Eraserhead

macrumors G4
Nov 3, 2005
10,434
12,250
UK
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.
 

Nutter

macrumors 6502
Original poster
Mar 31, 2005
432
0
London, England
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.
 

Eraserhead

macrumors G4
Nov 3, 2005
10,434
12,250
UK
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.

You can do that in code too ;). You just have to have the NSArrayController as an IBOutlet in the header file.
 

Nutter

macrumors 6502
Original poster
Mar 31, 2005
432
0
London, England
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.
 

Eraserhead

macrumors G4
Nov 3, 2005
10,434
12,250
UK
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.

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.
 

Nutter

macrumors 6502
Original poster
Mar 31, 2005
432
0
London, England
... 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.
 

Eraserhead

macrumors G4
Nov 3, 2005
10,434
12,250
UK
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.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.