实现搜索功能

时间:2016-02-24 14:10:14

标签: ios swift nsarray nsdictionary uisearchcontroller

您好我已经在我的应用上实现了自动完成搜索。当用户键入任何字符或单词时,我将城市存储在我的mysql数据库和应用程序中,应用程序从数据库中获取结果并显示它。现在我遇到了一个小的编程问题,我不知道如何解决它。

问题出在同一个数组中,我正在获得一个城市,我也得到了国家名称和州名。由于我只对不在州和国家的城市实施搜索,我实际上需要基于用户搜索城市显示的那些行的其他列(州,国家)。我会在此处粘贴代码以便更好地理解

class  CityTableViewController: UITableViewController, UISearchResultsUpdating {
    var dict = NSDictionary()
    var filterTableData = [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.filterTableData.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){

                cell.cityNameLabel.text = filterTableData[indexPath.row]

                cell.countryNameLabel.text =  get the country name

                 cell.stateNameLabel.text =  get stateName
                return cell

            }else{

                cell.cityNameLabel.text = (((self.dict["\(indexPath.row)"] as?NSDictionary)!["City"] as?NSDictionary)!["name"] as?NSString)! as String
                return cell
            }



        }

        func updateSearchResultsForSearchController(searchController: UISearchController) {
            filterTableData.removeAll(keepCapacity: false)
            let searchWord = searchController.searchBar.text!

            getCityNamesFromServer(searchWord)

            let searchPredict = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)
            print("searchPredict is \(searchController.searchBar.text!)")

            for var i = 0; i < self.dict.count; i++ {
                let cityName = (((self.dict["\(i)"] as?NSDictionary)!["City"] as?NSDictionary)!["name"] as?NSString)! as String

         let countryName = (((self.dict["\(i)"] as?NSDictionary)!["Country"] as?NSDictionary)!["name"] as?NSString)! as String

let stateName = (((self.dict["\(i)"] as?NSDictionary)!["State"] as?NSDictionary)!["name"] as?NSString)! as String
            newTableData.append(cityname)
            }

            let array = (newTableData as NSArray).filteredArrayUsingPredicate(searchPredict)
            print("array is\(array)")
            filterTableData = array as! [String]
            self.tableView.reloadData()
        }






        func getCityNamesFromServer(searchWord:String){


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



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

                if let result = result {
                    print(result)

                    self.dict = result

                }
            }

        }

    }

如果我尝试设置新的州和国家数组,那么数据就不会正确显示。城市不属于他自己的国家出现。那么我如何才能正确地保持秩序。

数组:

字典

 0 =     {
        City =         {
            code = 10430;
            "country_id" = 244;
            id = 8932;
            name = Laudium;
            "state_id" = 4381;
            "updated_at" = "<null>";
        };
        Country =         {
            id = 244;
            name = "South Africa";
        };
        State =         {
            "country_id" = 244;
            id = 4381;
            name = Gauteng;
        };
    }; etc

newTableData

["Lynnwood", "Lyndhurst", "Laudium"]

filterTableData

["Laudium", "La Lucia", "Lansdowne"] etc

1 个答案:

答案 0 :(得分:0)

您应该在字典中搜索匹配项并将匹配的键存储在数组中,并在结果中引用这些键。

func updateSearchResultsForSearchController(searchController: UISearchController) {

    let searchWord = searchController.searchBar.text!

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

使用此过滤后的密钥填写tableview:     let key = self.filteredKeys [indexPath.row]

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

cell.cityNameLabel.text = ((dictionary["City"] as? NSDictionary)!["name"] as? NSString)! as String

cell.countryNameLabel.text = ((dictionary["Country"] as? NSDictionary)!["name"] as? NSString)! as String

cell.stateNameLabel.text = ((dictionary["State"] as? NSDictionary)!["name"] as? NSString)! as String

return cell

只需保存此过滤字典(self.filteredDictionary)并使用它来填充tableView。

我认为另一个问题是,当您从getCityNamesFromServer:调用服务器的搜索方法(updateSearchResultsForSearchController:)时,来自服务器的响应是异步的,之后的过程就是使用旧的字典数据,因为新的数据在处理时尚未就绪。

你应该尝试使用这样的块完成来修改getCityNamesFromServer:方法:

func updateSearchResultsForSearchController(searchController: UISearchController) {
    // Get search word    
    getCityNamesFromServer(searchWord) { () -> Void in
            // Rest of the code comes here
    }
}
func getCityNamesFromServer(searchWord:String, completionHandler: (() -> Void) ) {
    let url:String = "http://localhost/"
    let params = ["city":searchWord]

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

        if let result = result {
            print(result)

            self.dict = result

        }
        completionHandler()
   }

}