I am looking for a decent solution to this problem. I am wanting to implement some simple search functionality on a TableView that I have.
All the examples I have found either use the deprecated UISearchDisplayController
or use the new UISearchController
but without NSFetchedResultsController
Currently this is populated using Core Data
/ NSFetchedResultsController
So far I have managed to get it to a point where I can gather the users' search string (woo!). I am aware that I may need a separate FRC
to perform the search on, but as mentioned above all attempts up to now have failed.
My class is conforming to the following protocols:
class JobListController: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate, UISearchBarDelegate{
I can't use UITableViewController
as I have already written loads of existing functionality that relies on this class being a UIViewController
I have my two IBOutlets
:
@IBOutlet var tblJobs : UITableView!
@IBOutlet weak var searchBar: UISearchBar!
and my empty arrays to hold my various Core Data
bits and bobs:
var workItems = [Work]()
var filteredWorkItems = [Work]()
Here is how I am initialising my FRC
, along with my MOC
and I've left in my empty second FRC
as I am quite sure it will be needed at some point:
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
lazy var fetchedResultsController: NSFetchedResultsController = {
let workFetchRequest = NSFetchRequest(entityName: "Work")
let primarySortDescriptor = NSSortDescriptor(key: "createdDate", ascending: true)
let secondarySortDescriptor = NSSortDescriptor(key: "town", ascending: true)
workFetchRequest.sortDescriptors = [primarySortDescriptor, secondarySortDescriptor]
let frc = NSFetchedResultsController(
fetchRequest: workFetchRequest,
managedObjectContext: self.managedObjectContext!,
sectionNameKeyPath: "createdDate",
cacheName: nil)
frc.delegate = self
return frc
}()
var searchResultsController: NSFetchedResultsController?
In my viewDidLoad
function I am setting up the delegates / data source for my table and the searchBar:
tblJobs.delegate = self
tblJobs.dataSource = self
searchBar.delegate = self
and here is the searchBar
function which is where I am up to. The stringMatch
variable is leftover from a previous attempt, I am hoping to be able to search by a multitude of different parameters here, but if I can get just one working it will be a solid start.
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
println("Search text is \(searchText)")
self.filteredWorkItems = self.workItems.filter({( work: Work) -> Bool in
//
let stringMatch = work.postcode.rangeOfString(searchText)
return stringMatch != nil
})
if(filteredWorkItems.count == 0){
searchActive = false;
} else {
searchActive = true;
}
self.tblJobs.reloadData()
}
Here is my cellForRowAtIndexPath
function to show how I am pulling data from the fetchedResultsController
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell = self.tblJobs.dequeueReusableCellWithIdentifier(
"JobCell", forIndexPath: indexPath)
as! JobTableViewCell
let workItem = fetchedResultsController.objectAtIndexPath(indexPath) as! Work
//...
return cell
}
So you can see I've got a few things going on here, ultimately I am wanting to figure out how I use my newly gotten searchText
string to query against my FRC
, and then for the results to filter properly in the View.
Update:
I have attempted to add the search string to my NSPredicate
in the FRC
like so:
lazy var fetchedResultsController: NSFetchedResultsController = {
../
workFetchRequest.predicate = NSPredicate(format:"title contains[cd] %@", savedSearchTerm!)
//...
return frc
}()
Which results in 'JobListController.Type' does not have a member named 'savedSearchTerm'
At the top of my class I have set it up like this:
var savedSearchTerm: NSString?
So not sure what I'm doing wrong?