user1hjgjhgjhggjhg
user1hjgjhgjhggjhg

Reputation: 1327

Autocomplete Search List issue In Swift

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

            }
        }

    }

}

Upvotes: 0

Views: 975

Answers (1)

dan
dan

Reputation: 9825

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()   
        }               
    }
}

Upvotes: 2

Related Questions