Learn Objective-C on the Mac - Mark Dalrymple [97]
Edit the three default values that are listed below Left Exprs Key paths, changing them to quoteText, character, and show.name. While you’re at it, click to turn on the Case insensitive and Diacritical mark insensitive checkboxes (see Figure 9-8).
Figure 9-8. Configuring an NSPredicateEditorRowTemplate
Then, examine the popup button in the row template itself. This will show three entries, whose names are the same as what you just entered for key paths. Change these to more human-readable names: Quotation, Character Name, and Show Name.
Now click on the upper row template, the one showing “Any of the following are true.” The configuration for this is very simple. Checkboxes let you choose to allow boolean AND, OR, and NOT for the user to search on. Enable all of those, to allow the most utility.
Now there’s just one more piece of configuration that we need to do. By default, NSPredicateEditor lets the user delete all the rows, right down to the last one, at which point there is no longer a “+” button to add any back in. Change this by selecting the predicate editor itself (not one of the row templates) and clicking to turn off the Can Remove All Rows checkbox in the Attributes Inspector.
Save your work, Build & Run in Xcode, and bask in the glory of QuoteMonger! You can now easily search through all saved quotes, using the three criteria we configured in the predicate editor.
Saving a Predicate
Before we call it a day, let’s add one final bit of polish that will make using QuoteMonger a friendly experience for our users. Right now, each time a user launches the app, it starts up with our silly default query. Wouldn’t it be nice if it instead showed the last query from the previous time it was running? It turns out that this is a piece of cake. NSPredicate has a handy method called predicateFormat that returns the predicate’s value in the form of a string. So, we can save the current searchPredicate’s string representation using NSUserDefaults when the user quits the app, and check for a saved string when the app launches. Open up QuoteMonger_AppDelegate.m, and make the following changes to the first part of its implementation (just add all the lines that appear in bold):
We start by defining a string, which will be used as a key to store and retrieve the predicate from the user’s preferences using NSUserDefaults. Then, we enhance the init method to look for a stored predicate. It first checks to see if a stored predicate string exists, and if it does, it populates the searchPredicate instance variable with a new predicate created from the format string. If there is no stored predicate, the default predicate is created instead.
Finally, we implement the applicationWillTerminate: method. This method is called automatically when the user quits the application, giving us a chance to do some final cleanup. Here, we convert the current search parameters (maintained in the searchPredicate instance variable) into a string, and save that string into the user’s preferences so that the same search will pop up the next time the user runs the app.
Save, Build & Run, then modify the search terms. Quit the app and run it again, and you should see your previous search terms show up again.
In Conclusion
In this chapter you’ve learned the basics of how to use NSPredicate to narrow down a Core Data result set. You’ve seen how an NSPredicate can be constructed in code, or in Interface Builder, or by user interaction with NSPredicateEditor. You’ve even gotten a hint of how these predicates