【发布时间】:2018-11-01 21:07:36
【问题描述】:
我遍历几个Urls,将它们转换为Data,然后将数据发送到Firebase Storage,然后当一切完成后将收集到的信息发送到Firebase Database
我使用 DispatchGroup() 的 .enter() 开始循环,一旦我将数据发送到 Storage 并获得一个值 url 字符串 absoluteString 我使用 .leave() 开始下一次迭代。
我意识到,在循环过程中,有几个点可能会发生错误:
- 一次进入
UrlSession - 曾经在 Storage 的
.putData函数中 - 在 Storage 的
.downloadURL(completion:...完成处理程序中一次 - 如果最终 downloadURL 的
?.absoluteString为 nil,则再次显示
如果我在其中任何一点出现错误,我会显示一个警报函数showAlert(),该函数会显示警报并取消带有session.invalidateAndCancel() 的 UrlSession。我取消所有内容,因为我希望用户重新开始。
由于 DispatchGroup() 一直挂在 .enter(),如何取消 DispatchGroup() 以停止循环?
var urls = [URL]()
var picUUID = UUID().uuidString
var dict = [String:Any]()
let session = URLSession.shared
let myGroup = DispatchGroup()
var count = 0
for url in urls{
myGroup.enter()
session.dataTask(with: url!, completionHandler: {
(data, response, error) in
if error != nil {
self.showAlert() // 1st point of error
return
}
DispatchQueue.main.async{
self.sendDataToStorage("\(self.picUUID)_\(self.count).jpg", picData: data)
self.count += 1
}
}).resume()
myGroup.notify(queue: .global(qos: .background) {
self.sendDataFromDictToFirebaseDatabase()
self.count = 0
self.session.invalidateAndCancel()
}
}
func sendDataToStorage(_ picId: String, picData: Data?){
dict.updateValue(picId, forKey:"picId_\(count)")
let picRef = storageRoot.child("pics")
picRef.putData(picData!, metadata: nil, completion: { (metadata, error) in
if error != nil{
self.showAlert() // 2nd point of error
return
}
picRef?.downloadURL(completion: { (url, error) in
if error != nil{
self.showAlert() // 3rd point of error
return
}
if let picUrl = url?.absoluteString{
self.dict.updateValue(picUrl, forKey:"picUrl_\(count)")
self.myGroup.leave() //only leave the group if a Url string was obtained
}else{
self.showAlert() // 4th point of error
}
})
})
}
func showAlert(){
// the DispatchGroup() should get cancelled here
session.invalidateAndCancel()
count = 0
UIAlertController...
}
func sendDataFromDictToFirebaseDatabase(){
}
【问题讨论】:
-
无论成功与否,都需要调用
leave。该组真的不应该是一个类属性。它应该是带有循环的代码的本地代码。 -
2 个问题。 1. 调用 leave 不会自动开始下一次迭代吗?例如,如果第一个循环出现问题,我播下警报,取消会话并调用.leave,第二个循环不会开始运行吗? 2.为什么组不应该是类属性? sendDataToStorage 是一个单独的函数,我需要调用 leave in
-
我想用@rmaddy 添加的一件事是你必须确保.leave() 等于.enter()。如果 .leave 大于 .enter(),应用程序将崩溃
-
@Karthick Ramesh 你能进一步解释一下吗?在每个错误点,我都使用 return 来防止其他任何东西运行。一旦我使用 .leave() 它将如何增加?
标签: ios swift loops grand-central-dispatch firebase-storage