我想在一个函数中运行2个异步代码并转义它们。我想首先下载Reciter信息,然后使用这些信息下载与Reciter相关联的图像。我正在使用Firestore。我尝试使用DispatchQueue和DispatchGroup,但我无法解决问题。我希望有一个人可以帮助我 :)
func getReciters(completion: @escaping (Bool) -> Void) {
var reciters = [Reciter]()
self.BASE_URL.collection(REF_RECITERS).getDocuments { (snapchot, error) in
if let error = error {
debugPrint(error)
completion(false)
// TODO ADD UIALTERCONTROLLER MESSAGE
return
}
guard let snapchot = snapchot else { debugPrint("NO SNAPSHOT"); completion(false); return }
for reciter in snapchot.documents {
let data = reciter.data()
let reciterName = data[REF_RECITER_NAME] as? String ?? "ERROR"
let numberOfSurahs = data[REF_NUMBER_OF_SURAHS] as? Int ?? 0
// **HERE I WANT TO DOWNLOAD THE IMAGES**
self.downloadImage(forDocumentID: reciter.documentID, completion: { (image) in
let reciter = Reciter(name: reciterName, image: nil, surahCount: numberOfSurahs, documentID: reciter.documentID)
reciters.append(reciter)
})
}
}
UserDefaults.standard.saveReciters(reciters)
completion(true)
}
你需要DispatchGroup
。
DispatchGroup
的实例。enter
。leave
的完成处理程序内部的循环中。notify
之后,闭包将在所有异步任务完成后执行。func getReciters(completion: @escaping (Bool) -> Void) {
var reciters = [Reciter]()
self.BASE_URL.collection(REF_RECITERS).getDocuments { (snapchot, error) in
if let error = error {
debugPrint(error)
completion(false)
// TODO ADD UIALTERCONTROLLER MESSAGE
return
}
guard let snapchot = snapchot else { debugPrint("NO SNAPSHOT"); completion(false); return }
let group = DispatchGroup()
for reciter in snapchot.documents {
let data = reciter.data()
let reciterName = data[REF_RECITER_NAME] as? String ?? "ERROR"
let numberOfSurahs = data[REF_NUMBER_OF_SURAHS] as? Int ?? 0
group.enter()
self.downloadImage(forDocumentID: reciter.documentID, completion: { (image) in
let reciter = Reciter(name: reciterName, image: nil, surahCount: numberOfSurahs, documentID: reciter.documentID)
reciters.append(reciter)
group.leave()
})
}
group.notify(queue: .main) {
UserDefaults.standard.saveReciters(reciters)
completion(true)
}
}
}