0

hello I have a very strange problem in my search functionality. I have successfully implemented the search functionality. I am getting a data from backend service. The problem is at some stage the data doesn't load up accurately in the suggestion area(tableView) according to the keywords typed. I also printing the result on console as well to check wether I am getting the accurate results against the keyword and the console shows accurate results, just the suggestion area doesn't load up exact result sometime. for example In my app If I want to search the city "Lahore". I typed full letters "Lahore"

It shows this enter image description here

but when I press x icon or backspace to remove the "e" it shows accurate results

enter image description here

I am just showing it for as an example. This is happening to almost all the time. Could you please take a look at my code and see whats wrong I am doing.

class CountryTableViewController: UITableViewController, UISearchResultsUpdating {

    var dict = NSDictionary()
    var filteredKeys = [String]()

    var resultSearchController = UISearchController()

    var newTableData = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.resultSearchController = ({

            let controller  = UISearchController(searchResultsController: nil)
            controller.searchResultsUpdater = self
            controller.dimsBackgroundDuringPresentation = false
            controller.searchBar.sizeToFit()
            self.tableView.tableHeaderView = controller.searchBar
            return controller


        })()

        self.tableView.reloadData()
    }

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

        if (self.resultSearchController.active) {

            return self.filteredKeys.count
        } else {

            return dict.count
        }

    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CountryTableViewCell

        if(self.resultSearchController.active){





                let cityName = (((self.dict["\(indexPath.row)"] as?NSDictionary)!["Country"] as?NSDictionary)!["city_name"] as?NSString)

               let stateName  = (((self.dict["\(indexPath.row)"] as?NSDictionary)!["Country"] as? NSDictionary)!["state_name"] as? NSString)

                 let shortName  = (((self.dict["\(indexPath.row)"] as?NSDictionary)!["Country"] as? NSDictionary)!["short_country_name"] as? NSString)


            if (cityName != "-" || shortName != "-"){
                cell.stateNameLabel.text = stateName as? String
                cell.cityNameLabel.text = cityName as? String
                 cell.shortNameLabel.text = shortName as? String

            }

                      return cell

        }else{
            if let cityName = (((self.dict["\(indexPath.row)"] as?NSDictionary)!["Country"] as?NSDictionary)!["city_name"] as?NSString){
            cell.cityNameLabel.text = cityName as String
            }
            return cell
        }



    }



    func updateSearchResultsForSearchController(searchController: UISearchController) {

        let searchWord = searchController.searchBar.text!

        getCountriesNamesFromServer(searchWord)

        self.filteredKeys.removeAll()

        for (key, value) in self.dict {

            let valueContainsCity: Bool = (((value as? NSDictionary)?["Country"] as? NSDictionary)?["city_name"] as? String)?.uppercaseString.containsString(searchWord.uppercaseString) ?? false

            let valueContainsCountry: Bool = (((value as? NSDictionary)?["Country"] as? NSDictionary)?["country_name"] as? String)?.uppercaseString.containsString(searchWord.uppercaseString) ?? false

            if valueContainsCity || valueContainsCountry{ self.filteredKeys.append(key as! String) }




        }

        self.tableView.reloadData()
    }




    func getCountriesNamesFromServer(searchWord:String){


        let url:String = "http://localhost"
        let params = ["keyword":searchWord]



        ServerRequest.postToServer(url, params: params) { result, error in

            if let result = result {
                print(result)



                self.dict = result

            }
        }

    }

}
user1hjgjhgjhggjhg
  • 1,237
  • 4
  • 15
  • 34

1 Answers1

2

You are reloading your table after your request starts instead of when it finishes, so your dict still has the results from the last query it ran.

Move everything in your updateSearchResults.. method that is after you call getCountriesNamesFromServer into the completion handler for your network request after you do self.dict = result

Your new methods would be:

func updateSearchResultsForSearchController(searchController: UISearchController) {    
    let searchWord = searchController.searchBar.text!    
    getCountriesNamesFromServer(searchWord)        
}

func getCountriesNamesFromServer(searchWord:String) {        
    let url:String = "http://localhost"
    let params = ["keyword":searchWord]

    ServerRequest.postToServer(url, params: params) { result, error in    
        if let result = result {
            print(result)

            self.dict = result

            self.filteredKeys.removeAll()

            for (key, value) in self.dict {
                let valueContainsCity: Bool = (((value as? NSDictionary)?["Country"] as? NSDictionary)?["city_name"] as? String)?.uppercaseString.containsString(searchWord.uppercaseString) ?? false

                let valueContainsCountry: Bool = (((value as? NSDictionary)?["Country"] as? NSDictionary)?["country_name"] as? String)?.uppercaseString.containsString(searchWord.uppercaseString) ?? false

                if valueContainsCity || valueContainsCountry {
                    self.filteredKeys.append(key as! String)
                }
            }

            self.tableView.reloadData()   
        }               
    }
}
dan
  • 9,695
  • 1
  • 42
  • 40
  • could you please edit my code. I am new so didn't understand what to do now. would be very thankful – user1hjgjhgjhggjhg Mar 02 '16 at 21:07
  • I added some code to my answer, you basically just have to cut and paste that block of code from one method to the other – dan Mar 02 '16 at 21:13