Swift 斯威夫特火力基地搜索是一个重新加载落后

Swift 斯威夫特火力基地搜索是一个重新加载落后,swift,firebase,firebase-realtime-database,Swift,Firebase,Firebase Realtime Database,我的应用程序中有一个搜索功能,除了它似乎落后一次之外,它工作得非常好。例如,如果我键入“S”,则不会显示任何内容,但如果我在“S”的所有结果显示后键入“a”。我尝试在fetch函数的末尾添加collectionView重载,但如果这样做,则不会显示任何内容 @objc func textFieldDidChange(_ textField: UITextField) { guard let text = textField.text else { return } if tex

我的应用程序中有一个搜索功能,除了它似乎落后一次之外,它工作得非常好。例如,如果我键入“S”,则不会显示任何内容,但如果我在“S”的所有结果显示后键入“a”。我尝试在fetch函数的末尾添加collectionView重载,但如果这样做,则不会显示任何内容

@objc func textFieldDidChange(_ textField: UITextField) {
    guard let text = textField.text else { return }

    if text.count == 0 {
        self.posts.removeAll()
        self.filteredPosts.removeAll()
    } else {
        fetchSearchedPosts(searchTerm: text)
    }
    self.collectionView.reloadData()
}

func fetchSearchedPosts(searchTerm: String) {
    self.collectionView.refreshControl?.endRefreshing()

    let ref = Database.database().reference().child("posts").queryOrdered(byChild: "title").queryStarting(atValue: searchTerm).queryEnding(atValue: "\(searchTerm)\u{f8ff}")
    ref.observeSingleEvent(of: .value) { (snapshot) in

        if !snapshot.exists() { return }

        guard let dictionaries = snapshot.value as? [String: Any] else { return }
        self.posts.removeAll()
        dictionaries.forEach({ (key, value) in

            guard let postDictionary = value as? [String: Any] else { return }
            guard let uid = postDictionary["uid"] as? String else { return }

            Database.fetchUserWithUID(uid: uid, completion: { (user) in

                let post = Post(postId: key, user: user, dictionary: postDictionary)

                let nowTimeStamp = Date().timeIntervalSince1970
                let dateTime = post.endTimeDate
                let timeStamp = dateTime.timeIntervalSince1970

                    if nowTimeStamp < timeStamp {

                    post.id = key
                    self.posts.append(post)

                    } else {
                        return
                    }
            })
            self.posts.sort(by: { (post1, post2) -> Bool in
                return post1.title.compare(post2.title) == .orderedAscending
            })
        })
        self.collectionView.reloadData()
    }
}
@objc func textField didchange(textField:UITextField){
guard let text=textField.text else{return}
如果text.count==0{
self.posts.removeAll()
self.filteredPosts.removeAll()
}否则{
fetchSearchedPosts(搜索术语:文本)
}
self.collectionView.reloadData()
}
func fetchSearchedPosts(searchTerm:String){
self.collectionView.refreshControl?.endRefresh()
让ref=Database.Database().reference().child(“posts”).queryOrdered(byChild:“title”).queryStart(atValue:searchTerm)。queryEnding(atValue:“\(searchTerm)\u{f8ff}”)
中的ref.observeSingleEvent(of:.值){(快照)
如果!snapshot.exists(){return}
guard let dictionaries=snapshot.value as?[String:Any]else{return}
self.posts.removeAll()
字典.forEach({(键,值)在
guard let postDictionary=值为?[String:Any]else{return}
guard let uid=postDictionary[“uid”]作为字符串else{return}
Database.fetchUserWithUID(uid:uid,完成:{(用户)在
让post=post(postId:key,user:user,dictionary:postdirectionary)
让nowTimeStamp=Date().timeIntervalSince1970
让dateTime=post.endTimeDate
让timeStamp=dateTime.timeIntervalSince1970
如果nowTimeStampBool-in
返回post1.title.compare(post2.title)=.orderedAscending
})
})
self.collectionView.reloadData()
}
}

您需要一个
DispatchGroup
,因为您有嵌套的异步调用

func fetchSearchedPosts(searchTerm: String) {

    self.collectionView.refreshControl?.endRefreshing() 
    let ref = Database.database().reference().child("posts").queryOrdered(byChild: "title").queryStarting(atValue: searchTerm).queryEnding(atValue: "\(searchTerm)\u{f8ff}")
   ref.observeSingleEvent(of: .value) { (snapshot) in

    if !snapshot.exists() { return }

    guard let dictionaries = snapshot.value as? [String: Any] else { return }
    self.posts.removeAll()
    let g = DispatchGroup()   ///// 1

    dictionaries.forEach({ (key, value) in

        guard let postDictionary = value as? [String: Any] else { return }
        guard let uid = postDictionary["uid"] as? String else { return }

        g.enter()   ///// 2
        Database.fetchUserWithUID(uid: uid, completion: { (user) in

            let post = Post(postId: key, user: user, dictionary: postDictionary)

            let nowTimeStamp = Date().timeIntervalSince1970
            let dateTime = post.endTimeDate
            let timeStamp = dateTime.timeIntervalSince1970

                if nowTimeStamp < timeStamp {

                    post.id = key
                    self.posts.append(post)

                } else {
                    g.leave()   ///// 3.a
                    return
                }
            g.leave()   ///// 3.b
        })
    })

    g.notify(queue:.main) {    ///// 4
      self.posts.sort(by: { (post1, post2) -> Bool in
           return post1.title.compare(post2.title) == .orderedAscending
       })  
       self.collectionView.reloadData()
     }
  }
}
func fetchSearchedPosts(searchTerm:String){
self.collectionView.refreshControl?.endRefresh()
让ref=Database.Database().reference().child(“posts”).queryOrdered(byChild:“title”).queryStart(atValue:searchTerm)。queryEnding(atValue:“\(searchTerm)\u{f8ff}”)
中的ref.observeSingleEvent(of:.值){(快照)
如果!snapshot.exists(){return}
guard let dictionaries=snapshot.value as?[String:Any]else{return}
self.posts.removeAll()
设g=DispatchGroup()//1
字典.forEach({(键,值)在
guard let postDictionary=值为?[String:Any]else{return}
guard let uid=postDictionary[“uid”]作为字符串else{return}
g、 回车()///2
Database.fetchUserWithUID(uid:uid,完成:{(用户)在
让post=post(postId:key,user:user,dictionary:postdirectionary)
让nowTimeStamp=Date().timeIntervalSince1970
让dateTime=post.endTimeDate
让timeStamp=dateTime.timeIntervalSince1970
如果nowTimeStampBool-in
返回post1.title.compare(post2.title)=.orderedAscending
})  
self.collectionView.reloadData()
}
}
}

有一个公认的答案-但是,另一个问题是collectionView在数据从Firebase返回之前被重新加载。这个
self.collectionView.reloadData()
应该位于Firebase闭包的最里面,以确保在加载所有数据之后调用它,所以就在
self.posts.append(post)
之后。另外,在返回所有数据之前,将调用self.posts.sort(by:{(post1,post2)。只是想澄清一下,以防出现其他计时问题。