swift - 如何在知道所有任务何时完成的同时异步初始化 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 异步加载数据,同时还可以设置侦听器。我也不想将闭包相互嵌套,因为它不会是异步的,而且也会很痛苦。
解决方案
我可能错了,但你应该把组留在你的块里,这是我如何使用组的例子
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()
}
}
推荐阅读
- amazon-web-services - 删除驻留在亚马逊 s3 上的存储桶内的子文件夹中的文件
- c++ - 为什么我的模板链接列表不起作用?
- python - 在 Discord.py 中查看频道的消息历史记录
- geocoding - 使用 HERE 地理编码和搜索 API v7 的街道交叉口坐标
- java - 检查是否选择了 switch case
- javascript - ES6 - 检查一个类是否属于某个类树
- java - 有一个免费的本地工具可以从 Spring Boot Java 应用程序的日志中创建见解,比如 Splunk?
- java - 将枚举列表转换为数组
- c# - 应该如何检测非等待任务的完成?
- python - conda:如何将频道 URL 转为在线