来自网址的Swift 3搜索表

时间:2016-12-22 17:15:24

标签: swift uitableview

我已经设置了一个表,通过从我的服务器请求json数据来填充。

我想在顶部实现一个搜索栏,根据搜索文本框中的字符串过滤结果。

我已经使用文本框中的“编辑已更改”操作并在每次按下某个键时调用'getdata()'函数。

我遇到的问题在较慢的互联网连接上尤其明显。

当用户输入名称时,在执行每个字母的功能时,代码重新加载表5-6次会有延迟。这看起来让用户感到困惑。

我是以正确的方式接近这个吗?有没有办法在每次按下一个键时取消之前执行的任何函数?

@IBAction func textUpdated(_ sender: Any) {
    if (textField.text != nil){
        getdata(searchString: textField.text!)
    }
}
override func viewDidLoad() {
    print(value)
    let nib = UINib(nibName: "vwTblCell2", bundle: nil)
    tableView.register(nib, forCellReuseIdentifier: "cell2")
}
override func viewDidAppear(_ animated: Bool) {
    getdata(searchString: "")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.tableData.count
}
// 3
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell  {
    let cell2: TblCell2 = self.tableView.dequeueReusableCell(withIdentifier: "cell2") as! TblCell2
    cell2.nameLabel.text = "\(tableData[indexPath.row] as String)"+" "+"\(tableLastName[indexPath.row] as String)"
    cell2.companyLabel.text = tableCompany[indexPath.row]
    cell2.jobTitleLabel.text = tableJobTitle[indexPath.row]
    let url = URL(string: "https://www.****.co.uk/wellpleased/backend/profileimages/\(tableImage[indexPath.row])")
    DispatchQueue.global().async {
        cell2.userImage.isHidden = true
        let data = try? Data(contentsOf: url!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
        DispatchQueue.main.async {
            if data != nil {
            cell2.userImage?.image = UIImage(data: data!)
                cell2.userImage.isHidden = false
            }
        }
    }
    return cell2
}
// 4
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print("Row \(tableID[indexPath.row]) selected")
    userSelect = tableID[indexPath.row]
    DispatchQueue.main.async {
        self.performSegue(withIdentifier: "goSwipeScreen", sender: self)
    }
}
// 5
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 90
}
func getdata(searchString: String){
    let defaults = UserDefaults()
    let userid = defaults.string(forKey: "id")
    let newSearchString = searchString.replacingOccurrences(of: " ", with: "%20")
    let url = NSURL(string: "https://www.asmserver.co.uk/wellpleased/backend/searchattendees.php?userid=\(userid!)&searchstring=\(newSearchString)&eventid=\(value as String)")
    let task = URLSession.shared.dataTask(with: url as! URL) { (data, response, error) -> Void in
        if let urlContent = data {
            do {
                if let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: []) as? [[String:AnyObject]] {
                    self.tableData.removeAll()
                    self.tableLastName.removeAll()
                    self.tableCompany.removeAll()
                    self.tableJobTitle.removeAll()
                    self.tableImage.removeAll()
                    self.tableID.removeAll()
                    var i = 0
                    while i < jsonResult.count {
                        self.tableData.append(jsonResult[i]["firstname"]! as! String)
                         self.tableLastName.append(jsonResult[i]["lastname"]! as! String)
                        self.tableCompany.append(jsonResult[i]["company"]! as! String)
                        self.tableJobTitle.append(jsonResult[i]["jobtitle"]! as! String)
                        self.tableImage.append(jsonResult[i]["image"]! as! String)
                        self.tableID.append(jsonResult[i]["userid"]! as! String)
                        i = i + 1
                    }
                }
            } catch {
                print("JSON serialization failed")
            }
        } else {
            print("ERROR FOUND HERE")
        }
        DispatchQueue.main.async(execute: { () -> Void in
            self.tableView.reloadData()
        })
        self.tableView.isUserInteractionEnabled = true
    }
    task.resume()
}

2 个答案:

答案 0 :(得分:0)

假设您的应用的初始状态显示所有可用行,则不要在服务器上进行过滤(通过为搜索字段中的每个更改发送新查询)。

使用描述here的UISearchBar和UISearchController以及许多其他地方仅过滤本地数据。

答案 1 :(得分:0)

我在电子商务应用程序中遇到了类似的问题,然后我确实解决了这个问题:

  1. Decalare全球searchTxt变量
  2. 将搜索字符串存储在textDidChange委托中并分配到searchTxt
  3. 使用Timer每3秒调用一次
  4. 调用选择器(searchUsingAPI),其中我添加了所有用于获取搜索结果的Web服务代码。
  5. 以下是带有方法名称的代码:

       var debounceTimer: NSTimer?
        func test() {
            if let timer = debounceTimer {
                timer.invalidate()
            }
            debounceTimer = NSTimer(timeInterval: 0.3, target: self, selector: Selector("searchUsingAPI"), userInfo: nil, repeats: false)
            NSRunLoop.currentRunLoop().addTimer(debounceTimer!, forMode: "NSDefaultRunLoopMode")
        } 
    

    // MARK:WEBSERVICE METHODS

    func searchUsingAPI() {
    
       //Web service fetching code goes here 
    }
    

    // MARK: - SEARCHBAR DELEGATES METHOD

    func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
    
            self.searchText = searchText
            test()
            pageIndex           = 0
            pageSize            = 0
            TOTAL_PAGE_COUNT    = 0
        }
    

    由于创建了Webservices,使用10 Records概念一次只提取Pagination,因此在textDidChange中我也初始化Pagination相关变量。

    这是解决方案之一,也可能是其他解决方案,但我这样解决了。 希望通过这种方式你也可以解决你的问题。如果有的话,请随时发表评论。