0

I am trying to implement a searchBar in my iOS App. I am searching country and city from the app. Country and city names are coming from the database. There are few problems which I am having is in my code.

First right now my code successfully searches the city but it isn't searching country name and I don't know how can I do a search in country names as well.

    func updateSearchResultsForSearchController(searchController: UISearchController) {

                let searchWord = searchController.searchBar.text!

                getCountriesNamesFromServer(searchWord)

                self.filteredKeys.removeAll()

                for (key, value) in self.dict {
                    let valueContainsSearchWord: Bool = (((value as? NSDictionary)?["City"] as? NSDictionary)?["name"] as? String)?.uppercaseString.containsString(searchWord.uppercaseString) ?? false
                    if valueContainsSearchWord {
                        self.filteredKeys.append(key as! String)
                    }
                }

                self.tableView.reloadData()
            }

Second issue Is I want to get the ids of selected country and city as well which user selects on the app. For your information I am getting the ids from the server as well

Here is my full code

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 key = self.filteredKeys[indexPath.row]

            let dictionary = self.dict[key] as! NSDictionary

            if

                let cityName = (((self.dict["\(indexPath.row)"] as?NSDictionary)!["City"] as?NSDictionary)!["name"] as?NSString),

               let stateName  = (((self.dict["\(indexPath.row)"] as?NSDictionary)!["State"] as? NSDictionary)!["name"] as? NSString),

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

            {
                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)!["City"] as?NSDictionary)!["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 valueContainsSearchWord: Bool = (((value as? NSDictionary)?["City"] as? NSDictionary)?["name"] as? String)?.uppercaseString.containsString(searchWord.uppercaseString) ?? false
            if valueContainsSearchWord {
                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 is\(result)")

                self.dict = result

            }
        }

    }

}

dictionary structure:

{
    0 =     {
        City =         {
            code = 10409;
            "country_id" = 244;
            id = 8727;
            iso = "ZA-05";
            lat = "-32.7833000";
            longi = "26.8333000";
            name = Alice;
            "state_id" = 4379;
        };
        Country =         {
            id = 244;
            name = "South Africa";
            "short_name" = ZA;
        };
        State =         {
            "country_id" = 244;
            id = 4379;
            name = "Eastern Cape";
        };
    };
hellosheikh
  • 2,929
  • 8
  • 49
  • 115
  • Try provide a short sample `dict` structure in the question. The second part of the question should be related to `tableView:didSelectRowAtIndexPath` delegate method. – zc246 Mar 02 '16 at 10:43

1 Answers1

0

You are only searching for ["City"] key in dicitionay, should add ["Country"] key too.

for (key, value) in self.dict {

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

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

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

    }

uppercaseString - is your city and country names in uppercaseString? if not do a lowerCaseString

this will get you city id and country id.

(((self.dict["\(indexPath.row)"] as?NSDictionary)!["City"] as?NSDictionary)!["id"] as?NSString)
(((self.dict["\(indexPath.row)"] as?NSDictionary)!["Country"] as?NSDictionary)!["id"] as?NSString)
hellosheikh
  • 2,929
  • 8
  • 49
  • 115
UIResponder
  • 785
  • 9
  • 15
  • yes that is what I am asking. How can I do here country search too. I mean how can I add another field here too. I am talking about the syntax – hellosheikh Mar 02 '16 at 10:32
  • is Country the key? for Cities in the country? – UIResponder Mar 02 '16 at 10:33
  • let countryName = (((self.dict["\(indexPath.row)"] as?NSDictionary)!["Country"] as? NSDictionary)!["name"] as? NSString) – hellosheikh Mar 02 '16 at 10:36
  • this prints the country Name – hellosheikh Mar 02 '16 at 10:36
  • let valueContainsCity: Bool = (((value as? NSDictionary)?["City"] as? NSDictionary)?["name"] as? String)?.uppercaseString.containsString(searchWord.uppercaseString) ?? false let valueContainsCountry: Bool = (((value as? NSDictionary)?["Country"] as? NSDictionary)?["name"] as? String)?.uppercaseString.containsString(searchWord.uppercaseString) ?? false if valueContainsCity || valueContainsCountry{ self.filteredKeys.append(key as! String) } try this. – UIResponder Mar 02 '16 at 10:40
  • okay Great It works. Now my another issue which is to get the id and country from selected row. I know it will be done in the the didSelectRowAtIndexPath method but I don't know how can I get the selected row country id, or city id... – hellosheikh Mar 02 '16 at 10:46
  • give the country dictionary structure entirely – UIResponder Mar 02 '16 at 10:48