Swift 搜索栏 - 使用 Alamofire 请求更新表格视图

Posted

技术标签:

【中文标题】Swift 搜索栏 - 使用 Alamofire 请求更新表格视图【英文标题】:Swift search bar - updating table view with Alamofire request 【发布时间】:2017-02-09 14:31:01 【问题描述】:

我已经在我的数据库上进行了一些字符串搜索,并在用户在搜索栏上按下第三个字符后返回 JSON,然后我将所有结果附加到一个数组并用数据填充 tableview。

虽然我正在处理一个问题。当我搜索 mens 时,我得到的结果出现在 tableview 上

如果我删除所有文本并写女性,一切都很好...但是当我删除一些字符串等时,我在 tableview cellForRowAt 内收到错误index out of range。我猜它会中断,因为 tableview 没有时间获取附加的数组并填充单元格。

我想知道的是如何在不设置查询或reloadData() 的时间延迟的情况下使其工作。我不想要时间延迟的原因是因为某些用户的 iPhone 可能很慢 - 旧 iPhone,即使延迟 2 秒,它也可能崩溃。

这是我的代码

class SearchViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UISearchControllerDelegate

@IBOutlet weak var searchResultTable: UITableView!
    let searchController = UISearchController(searchResultsController: nil)

    var filteredData = [Products]()

override func viewDidLoad() 
        super.viewDidLoad()


        self.navigationController?.isNavigationBarHidden = true
        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        definesPresentationContext = true
        searchResultTable.tableHeaderView = searchController.searchBar

        searchController.searchBar.delegate = self

    


func searchBarSearchButtonClicked(_ searchBar: UISearchBar) 
        searchBar.resignFirstResponder()
    


    func getSearch(completed: @escaping DownloadComplete, searchString: String) 
        if filteredData.isEmpty == false 
            filteredData.removeAll()
        
        let parameters: Parameters = [
            "action" : "search",
            "subaction" : "get",
            "product_name"  : searchString,
            "limit" : "0,30"
        ]


        Alamofire.request(baseurl, method: .get, parameters: parameters).responseJSON  (responseData) -> Void in
            if((responseData.result.value) != nil) 
                let result = responseData.result

                if let dict = result.value as? Dictionary<String, AnyObject>
                    if let list = dict["product_details"] as? [Dictionary<String, AnyObject>] 

                        for obj in list 
                            let manPerfumes = Products(productDict: obj)
                            self.filteredData.append(manPerfumes)
                        


                    
                
                completed()
            
        
    


func numberOfSections(in tableView: UITableView) -> Int 

        return 1

    
    func tableView(_ tableView: UITableView,
                   heightForRowAt indexPath: IndexPath) -> CGFloat 
        return 170
    

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

        return filteredData.count
    

    func tableView(_ tableView: UITableView,
                   cellForRowAt indexPath: IndexPath) -> UITableViewCell 

            let cell:iPhoneTableViewCell = tableView.dequeueReusableCell(withIdentifier: "iPhoneTableCell", for: indexPath) as! iPhoneTableViewCell

            let prods = self.filteredData[indexPath.row] //HERE I GET THE ERROR
            cell.configureCell(products: prods)

            return cell

    



extension SearchViewController: UISearchResultsUpdating 

    func updateSearchResults(for searchController: UISearchController) 

        if (searchController.searchBar.text?.characters.count)! >= 3 
                    self.getSearch(completed: 
                    self.searchResultTable.reloadData()

                    self.searchResultTable.setContentOffset(CGPoint.zero, animated: true)
                , searchString: searchController.searchBar.text!)
         else 
            self.searchResultTable.reloadData()
        


    

【问题讨论】:

【参考方案1】:

看起来您正在更改 filteredData 的状态,而 tableView 正在更改 reloadData。如果numberOfRowsForSection 返回 3,然后用户点击删除键,例如,数组大小将变为 0。这可能是 cellForRow 在请求索引 0,1 或 2 时抛出异常的原因。

【讨论】:

以上是关于Swift 搜索栏 - 使用 Alamofire 请求更新表格视图的主要内容,如果未能解决你的问题,请参考以下文章

使用 Alamofire 搜索从 swift 2 转换为 swift 3 时出错

Swift:Alamofire 文档

删除所有之前的 UITableViewCell Swift 3/4 iOS

Alamofire Swift HTTPPost 登录和 JSON 响应

使用 Alamofire Swift3 发送复杂参数得到状态码 500 错误

如何在 swift 5 中使用 alamofire 对登录到我的 iOS 应用程序的用户进行身份验证?