Evelyn
Evelyn

Reputation: 186

How to use search to search through multiple fields in Swift?

I'm trying get my search results to retrieve data from: name, dispensaryName, brand, category, & strain from my ProductList Class which retrieves the data from my Firestore as the search results

I think I found where to find the solution for how to allow the search to work correctly so that it can use all the required fields from my search

the problem is in my SearchbarDelegate extension inside the function I just don't know how to modify it to have name, dispensaryName, brand, category, and strain all be searched in unison and presented in the search results

its not working quite right since every time I run it, it looks for one field or the other, never all 5 fields at the same time upon running the simulator

I have tested the code for the searchbar but it still doesn't seem to work right

VARIBLES

   @IBOutlet weak var searchBar: UISearchBar!
   @IBOutlet weak var productListTableView: UITableView!

   var productInventory: [ProductList] = []
   var productSetup: [ProductList] = []

TAVBLEVIEW

extension ProductListController: UITableViewDelegate, UITableViewDataSource {
        func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

            if searchBar.text != "" {
                 return self.productInventory.count
            }
            return productSetup.count
        }

         func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            guard let cell =   tableView.dequeueReusableCell(withIdentifier: "ProductListCell") as?
    ProductListCell else { return UITableViewCell() }

            //search not empty
            if searchBar.text != "" {
            cell.configure(withProduct: productInventory[indexPath.row])
        }else{

            cell.configure(withProduct: productSetup[indexPath.row])
        }



        return cell
        }

   }

SEARCHBAR DELEGATE

    extension ProductListController : UISearchBarDelegate
    {
       func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
                productInventory = self.productSetup.filter({ (products) -> Bool in
                   return products.name.lowercased().range(of: searchText.lowercased()) != nil
                })
                productInventory = self.productSetup.filter({ (products) -> Bool in
                   return products.dispensaryName.lowercased().range(of: searchText.lowercased()) != nil
                })
                productInventory = self.productSetup.filter({ (products) -> Bool in
                  return products.brand.lowercased().range(of: searchText.lowercased()) != nil
                })
                productInventory = self.productSetup.filter({ (products) -> Bool in
                  return products.category.lowercased().range(of: searchText.lowercased()) != nil
                })
                productInventory = self.productSetup.filter({ (products) -> Bool in
                  return products.strain.lowercased().range(of: searchText.lowercased()) != nil
               })

          self.productListTableView.reloadData()
         }
}

Upvotes: 1

Views: 1518

Answers (1)

rmaddy
rmaddy

Reputation: 318794

You want just one filter. Just put all of the conditions inside that one filter.

productInventory = self.productSetup.filter({ (products) -> Bool in
   return products.name.lowercased().range(of: searchText.lowercased()) != nil ||
          products.dispensaryName.lowercased().range(of: searchText.lowercased()) != nil ||
          products.brand.lowercased().range(of: searchText.lowercased()) != nil
   // Add the rest as needed.
})

Note that using range with the appropriate options is better.

productInventory = self.productSetup.filter({ (products) -> Bool in
   return products.name.range(of: searchText, options: [ .caseInsensitive, .diacriticInsensitive ]) != nil ||
          products.dispensaryName.range(of: searchText, options: [ .caseInsensitive, .diacriticInsensitive ]) != nil ||
          products.brand.range(of: searchText, options: [ .caseInsensitive, .diacriticInsensitive ]) != nil
   // Add the rest as needed.
})

Upvotes: 4

Related Questions