I'm trying to implement search code in my CoreData-based iPhone app. I'm not sure how to proceed. The app already has an NSFetchedResultsController with a predicate to retrieve the data for the primary TableView. I want to make sure I'm on the right path before I change too much code. I'm confused because so many of the examples are array-based instead of CoreData.
Here are some questions:
-
Do I need to have a second NSFetchedResultsController that retrieves only the matching items or can I use the same one as the primary TableView?
-
If I use the same one, is it as simple as clearing the FRC cache and then changing the predicate in the handleSearchForTerm:searchString method? Does the predicate have to contain the initial predicate as well as the search terms or does it remember that it used a predicate to retrieve data in the first place?
-
How do I get back to the original results? Do I just set the search predicate to nil? Won't that kill the original predicate that was used to retrieve the FRC results in the first place?
If anyone has any examples of code using search with the FRC, I would greatly appreciate it!
Best Answer
I actually just implemented this on one of my projects (your question and the other wrong answer hinted at what to do). I tried Sergio's answer but had exception issues when actually running on a device.
Yes you create two fetch results controllers: one for the normal display and another one for the UISearchBar's table view.
If you only use one FRC (NSFetchedResultsController) then the original UITableView (not the search table view that is active while searching) will possibly have callbacks called while you are searching and try to incorrectly use the filtered version of your FRC and you will see exceptions thrown about incorrect number of sections or rows in sections.
Here is what I did: I have two FRCs available as properties fetchedResultsController and searchFetchedResultsController. The searchFetchedResultsController should not be used unless there is a search (when the search is canceled you can see below that this object is released). All UITableView methods must figure out what table view it will query and which applicable FRC to pull the information from. The FRC delegate methods must also figure out which tableView to update.
It is surprising how much of this is boilerplate code.
Relevant bits of the header file:
relevent bits of the implementation file:
I created a helpful method to retrieve the correct FRC when working with all of the UITableViewDelegate/DataSource methods:
Delegate methods for the search bar:
make sure that you use the correct table view when getting updates from the FRC delegate methods:
Other view information:
FRC creation code: