尝试搜索 Firestore 并重新加载 tableview 时出现 SearchBar 问题

SearchBar problem while trying to search Firestore and reload the tableview

我有一个 tableView,我使用无限滚动来批量填充 firestore 数据。我还有一个搜索栏,我正在尝试使用文本栏中的文本查询 firestore,然后将其填充到 tableview 中。我有 3 个主要问题。

  1. 当我第一次点击搜索时,我得到一个空数组和一个空的表格视图,但是当我第二次点击搜索时,一切似乎都很好。

  2. 当我最终填充搜索到的内容时,我想在滚动时停止获取新内容。

  3. 如果我输入了错误的字词并按搜索,我会得到之前的搜索,然后 "No Ingredients found" 打印两次。

这是我的搜索栏代码:

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        guard let text = searchBar.text else {return}
        searchIngredients(text: text)
        self.searchBarIngredient.endEditing(true)
        print("\(searchIngredients(text: text))")
    }

点击搜索时的功能代码

func searchIngredients(text: String) -> Array<Any>{

        let db = Firestore.firestore()

        db.collection("Ingredients").whereField("compName", arrayContains: text).getDocuments{ (querySnapshot, err) in
            if let err = err {
                print("\(err.localizedDescription)")
                print("Test Error")
            } else {
                if (querySnapshot!.isEmpty == false){
                    self.searchedIngredientsArray = querySnapshot!.documents.compactMap({Ingredients(dictionary: [=11=].data())})

                }else{
                    print("No Ingredients found")
                }
            }
        }

         self.tableView.reloadData()
         ingredientsArray = searchedIngredientsArray

        return ingredientsArray

    }

最后是滚动代码

func scrollViewDidScroll(_ scrollView: UIScrollView) {

        let off = scrollView.contentOffset.y
        let off1 = scrollView.contentSize.height

        if off > off1 - scrollView.frame.height * leadingScreensForBatching{
            if !fetchMoreIngredients && !reachEnd{
                beginBatchFetch()
            }
        }
    }

我不写 beginBatchFetch() 是因为它工作正常而且我认为不相关。 提前致谢。

您问题中的问题是 Firestore 是

Firestore 需要时间 return 您请求的文档,并且该数据仅在调用该函数的闭包内有效。闭包外的代码将在闭包内的数据可用之前执行。

事情是这样的。

func searchIngredients(text: String) -> Array<Any>{
    let db = Firestore.firestore()
    db.collection("Ingredients").whereField("compName", arrayContains: text).getDocuments{ (querySnapshot, err) in
        //the data has returned from firebase and is valid
    }
    //the code below here will execute *before* the code in the above closure
    self.tableView.reloadData()
    ingredientsArray = searchedIngredientsArray
    return ingredientsArray
}

发生的事情是在数组中有任何数据之前刷新 tableView。

您还在填充 ingredientsArray 之前 returning 了它。更重要的是,通常可以(并且应该)避免尝试 return 来自异步函数的值。

解决方法是在闭包内处理数据

class ViewController: NSViewController {
   var ingredientArray = [String]()
   func searchIngredients(text: String) {
         let db = Firestore.firestore()
         db.collection("Ingredients").whereField("compName", arrayContains: text).getDocuments{ (querySnapshot, err) in
             //the data has returned from firebase and is valid
             //populate the class var array with data from firebase
             //    self.ingredientArray.append(some string)
             //refresh the tableview
         }
     }

请注意,searchIngredients 函数不应 return 值 - 也不需要