0

So I have an app that lets users select movies from a list in tableview (populated by api), tapping on a movie presents a view with more details. I would like to implement a search bar so users can search for specific movies, however I am having some trouble

I assumed the following function would make movies searchable for the following tableview

 var newMovies: [NSDictionary] = []

...

 func searchBar() {

        let searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 50))
        searchBar.delegate = self
        searchBar.showsScopeBar = true
        searchBar.tintColor = UIColor.lightGray
        self.tableView.tableHeaderView = searchBar
    }

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        if searchText == "" {
            fetchMovies()
        }
        else {
            if searchBar.selectedScopeButtonIndex == 0 {
                newMovies = newMovies.filter({ (NSDictionary) -> Bool in
                    return NSDictionary.lowercased().contains(searchText.lowercased())
                })
            }
            else {

            }
        }
    }


 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{

        return newMovies.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {



        let cell = tableView.dequeueReusableCell(withIdentifier: "MovieCell", for: indexPath)  as! MovieSearchTableViewCell
        let movie =  newMovies[indexPath.row]
        let title = movie["title"] as! String
        let overview = movie["overview"] as! String

        cell.titleLabel.text = title
    cell.overviewLabel.text = overview

However this presents 2 errors on the line;

return NSDictionary.lowercased().contains(searchText.lowercased())

Value of type 'Any' has no member 'contains'

Value of type 'NSDictionary' has no member 'lowercased'

should I be returning something other than NSDictionary?

Astiop
  • 21
  • 1
  • What does your movie Model object look like? Where are your unfiltered movies and what do they look like? – Rob C Apr 18 '20 at 01:53
  • @Rob there are no unfiltered movies the filtered movies variable was the result of some poor experimentation with the code, I've updated the variable name to reflect this, im not sure what you mean by movie Model object – Astiop Apr 18 '20 at 02:18
  • Ah, I see, you're just using a dictionary to represent your movie. I assume that `fetchMovies` just resets the newMovies array with its original values? – Rob C Apr 18 '20 at 02:30
  • @Rob basically, yes `fetchMovies` creates a URLRequest to get the JSON data and assign it to the dictionary, That being said is it possible to implement a search function having done it this way? – Astiop Apr 18 '20 at 02:41
  • You can do it that way but it's inefficient. Hint: Use two arrays, one for search-mode and one for non-search-mode. Use a boolean flag to indicate you are in search mode. – Rob C Apr 18 '20 at 02:48

1 Answers1

0

Assuming you are searching for matching titles you would want to do this:

newMovies = newMovies.filter({ movie in
    guard let title = movie["title"] as? String else { return false }
    return title.lowercased().contains(searchText.lowercased())
})
Rob C
  • 4,877
  • 1
  • 11
  • 24