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

Swift 尝试搜索Firestore并重新加载tableview时出现搜索栏问题,swift,firebase,uitableview,google-cloud-firestore,uisearchbar,Swift,Firebase,Uitableview,Google Cloud Firestore,Uisearchbar,我有一个tableView,我使用无限滚动来批量填充firestore数据。我还有一个搜索栏,我试图用文本栏中的文本查询firestore,然后在tableview中填充它。我有三个主要问题 当我第一次单击“搜索”时,我得到一个空数组和一个空表视图,但当我第二次单击“搜索”时,一切似乎都很好 当我最终填充搜索内容时,我希望在滚动时停止获取新内容 如果我输入了一个错误的单词,然后按search,那么我会得到上一次搜索,然后打印两次“未找到任何成分” 这是我的搜索栏代码: func searchBa

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

  • 当我第一次单击“搜索”时,我得到一个空数组和一个空表视图,但当我第二次单击“搜索”时,一切似乎都很好

  • 当我最终填充搜索内容时,我希望在滚动时停止获取新内容

  • 如果我输入了一个错误的单词,然后按search,那么我会得到上一次搜索,然后打印两次“未找到任何成分”

  • 这是我的搜索栏代码:

    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: $0.data())})
    
                    }else{
                        print("No Ingredients found")
                    }
                }
            }
    
             self.tableView.reloadData()
             ingredientsArray = searchedIngredientsArray
    
            return ingredientsArray
    
        }
    
    我不写beginBatchFetch(),因为它工作得很好,我认为它与此无关。
    提前感谢。

    您的问题是Firestore是

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

    这就是发生的事情

    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
    }
    

    请注意,SearchComponents函数不应返回值,也不需要

    感谢您的回答。你让我明白了很多,这很有效。现在的问题是它打印了两次“未找到任何成分”。@NickStefanidis好吧,可能函数被调用了两次,或者print语句在循环中。该函数对我有效,只打印一次。也许用更新后的代码和Firestore结构的一个片段问另一个问题会有所帮助。谢谢。这是我的错误。还有一件事。我有无限的卷轴。当我有已建立的单元格时,是否可以停止提取;因为我有同义词,所以将有多个。@Nickstevanidis通常,如果您想要无限滚动,您将对数据进行分页,以便您的应用程序一次加载10行,然后,当用户滚动时,它将加载下一个10等。Firestore指南中有一些关于我成功分页数据的重要信息,这不是问题所在。但是,当我搜索某个内容并用找到的数据重新加载tableView时,分页会在我滚动之后再次开始。无法禁用滚动,因为数据可能超过屏幕高度。
    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
    }
    
    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
             }
         }