首页 > 解决方案 > 如何在知道所有任务何时完成的同时异步初始化 firebase firestore 侦听器?

问题描述

基本上,在我的应用程序启动时,我想从大约 4-5 个不同的文档中加载来自 firebase 的最新数据。然后我还想设置一个监听器来监听数据的变化。我通过调用 4-5 个以 adispatchGroup作为参数的类似函数来做到这一点。我可能完全错误地接近这个,但我想不出任何其他方法来做到这一点。我只想加载这些文档,设置监听器,并在应用程序启动时加载这些文档时采取某些行动。

// 应用启动

let dispatch = DispatchGroup()

getFirebaseDocument1(dispatch: dispatch)
getFirebaseDocument2(dispatch: dispatch)
getFirebaseDocument3(dispatch: dispatch)
getFirebaseDocument4(dispatch: dispatch)
getFirebaseDocument5(dispatch: dispatch)


dispatch.notify(queue:main) {
// execute some code to execute after all the documents are fetched
}




// typical getFirebaseDocument code

dispatch.enter()

let ref = someFirestoreReference

ref.addSnapshotListener { (snapshot, error) in
if let error = error{
   // handle error
} else {
// load the document



}
dispatch.leave()

}

该代码在启动时运行良好,但在侦听器收到更新时崩溃。我知道这是因为dispatch.leave()在侦听器函数中调用了。但是,我似乎无法找到一个聪明的解决方案,可以在启动时从 firebase 异步加载数据,同时还可以设置侦听器。我也不想将闭包相互嵌套,因为它不会是异步的,而且也会很痛苦。

标签: swiftfirebaseasynchronousgrand-central-dispatch

解决方案


我可能错了,但你应该把组留在你的块里,这是我如何使用组的例子

class func getRates(completion: @escaping EmptyBlock) {
    let eurRequest = APIConfigs.request(part: "rs/price/history")
    let usdRequest = APIConfigs.request(part: "rs/price/history/usd")
    let group = DispatchGroup()
    group.enter()
    sendRequest(request: eurRequest, method: .get, parameters: ServerParameters.rates()) { response in
        Course.current.addRate(rates: ratesRequest(response: response), type: .eur)
        group.leave()
    }
    group.enter()
    sendRequest(request: usdRequest, method: .get, parameters: ServerParameters.rates()) { response in
        Course.current.addRate(rates: ratesRequest(response: response), type: .usd)
        group.leave()
    }

    group.notify(queue: .main) {
        completion()
    }
}

推荐阅读