Search code examples
arraysswiftfilteringnspredicate

Filter array of objects on property with NSPredicate


I have an array of Studios. Each studio, has a property called studioName.

I need my searchfield to filter the studios, based on the studioName, applied to the searchfield by the user.

Here's my current code:

var studios = [Studio]()
var filteredStudios = [Studio]()
var studiosToDisplay = [Studio]()

func updateSearchResultsForSearchController(searchController: UISearchController) {
    let searchText = searchController.searchBar.text

    print("SEARCH TEXT: \(searchText)")

    if searchText == nil || searchText!.isEmpty {
        studiosToDisplay = studios
        self.resultTableView.reloadData()
        NSNotificationCenter.defaultCenter().postNotificationName("showResultsBeforeSearchingNotification", object: nil) //Calls SearchVC
    } else {
        studiosToDisplay.removeAll()
        let searchPredicate = NSPredicate(format: "studioName CONTAINS[c] %@", searchText!)
        let array = (self.studios as NSArray).filteredArrayUsingPredicate(searchPredicate)
        studiosToDisplay = array as! [Studio]
        self.resultTableView.reloadData()
    }
}

It's just not working wight, right now.. It filters, but I end up with the same Studio left each time, no matter what I put in the searchfield.

I guess I need to make the predicate know, that it has to look at the single object in the array, each time. But I just can't figure out how. I tried to add "ANY" in the format, but that crashes my app.


Solution

  • This is unnecessarily complex. There's no need for NSPredicate here.

    var studios = [Studio]()
    var filteredStudios = [Studio]()
    var studiosToDisplay = [Studio]()
    
    func updateSearchResultsForSearchController(searchController: UISearchController) {
        let searchText = searchController.searchBar.text
    
        print("SEARCH TEXT: \(searchText)")
    
        if let searchText = searchText, !searchText.isEmpty {
            studiosToDisplay = studios.filter{ $0.studioName.contains(searchText) }
        }
        else {
            studiosToDisplay = studios
            NSNotificationCenter.defaultCenter().postNotificationName("showResultsBeforeSearchingNotification", object: nil) //Calls SearchVC
        }
    
        self.resultTableView.reloadData()
    }