嵌套调度组Swift [英] Nested Dispatch Groups Swift
问题描述
当用户在我的应用程序中创建一个新组时,我必须将邀请推送到数据库以及其他信息。我已经开始使用调度组,以便跟踪所有信息何时成功发出,以便我可以关闭视图。
我试图使用邀请的调度组和所有数据的另一个调度组。下面是我所拥有的: 正如你所看到的,当 我是Dispatch组的新手,希望知道这是否是正确的处理方式。 检查所有的代码是非常重要的路径覆盖了 When a user creates a new group in my app I have to push invites to the database as well as other information. I've started using Dispatch Groups in order to keep track of when all the information is successfully sent out so I can dismiss the view. I'm trying to use a dispatch group for the invites and another dispatch group for all the data. Here's what I have: As you can see, when the I'm new to Dispatch groups and want to hear if this is the correct approach to be taking with this sort of task. This is a very good approach for async task tracking. It is important to check if all code paths are covered with In general always also make sure that all completion blocks are called in all of the code paths of methods you use. There always may be a bug in Firebase or there may be something about the completion not being called in the documentation of those methods. But again, this is the way to go. 这篇关于嵌套调度组Swift的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
$ p $ //将新数据推送到db
func createGroup(onSccess completion:@escaping() - > Void){
let inviteDispatchGroup = DispatchGroup()
let dataDispatchGroup = DispatchGroup()
let uid = FIRAuth.auth()?。currentUser?.uid
let name = String(uid!)+_+ nameTextField.text!
//推送邀请
dataDispatchGroup.enter()
邀请邀请{
inviteDispatchGroup.enter()
let ref = FIRDatabase.database( ).reference()。child(users)。child(invite.id).child(invites)
ref.updateChildValues([name:nameTextField.text!]){(error,ref) - >无效
inviteDispatchGroup.leave()
}
}
inviteDispatchGroup.notify(队列:DispatchQueue.main,执行:{
dataDispatchGroup.leave()
)}
//存储图片
dataDispatchGroup.enter()
let storageRef = FIRStorage.storage()。reference()。child(profile_images)。child \(name).png)
如果let uploadData = UIImagePNGRepresentation(profImage.resizeImage(targetSize:CGSize(width:500,height:Int(500 *(profImage.size.height / profImage.size.width )))){
storageRef.put(uploadData,metadata:nil,completion:{(metadata,error)in
dataDispatchGroup.leave()
))
}
$ b $ // store pet info
dataDispatchGroup.enter()
let petRef = FIRDatabase.database()。reference()。child(pets)。child(name)
petRef.setValue([mod:uid !,name:nameTextField.text !,members:[uid!]]){(error,ref) - >无效
dataDispatchGroup.leave()
}
$ b $ //存储用户信息
dataDispatchGroup.enter()
let userRef = FIRDatabase.database() .reference()。child(users)。child(uid!)。child(pets)
userRef.updateChildValues([name:true]){(error,ref) - >无效
dataDispatchGroup.leave()
}
dataDispatchGroup.notify(队列:DispatchQueue.main,执行:{$ b $完成()
})
$ b invitesDipatchGroup code>完成,相应的
dataDispatchGroup
剩下。
<解决方案这是一个非常好的异步任务跟踪方法。
leave()
。如果如果let
不具有不可选的值,那么您有一个潜在的错误。在这里修正:
func createGroup(onSccess completion:@escaping() - > Void){
[.. 。)
//存储图片
dataDispatchGroup.enter()
let storageRef = FIRStorage.storage()。reference()。child(profile_images)。child(\(name ).png)
如果let uploadData = UIImagePNGRepresentation(profImage.resizeImage(targetSize:CGSize(width:500,height:Int(500 *(profImage.size.height / profImage.size.width))))) {
storageRef.put(uploadData,metadata:nil,completion:{(metadata,error)in
dataDispatchGroup.leave()
})
} else {
dataDispatchGroup.leave()
}
[...]
}
一般来说,也要确保在所有使用的方法的代码路径中调用所有完成块。在Firebase中总会有一个错误,或者在这些方法的文档中可能会有一些关于完成的内容。但是,这又是一条路。// Push new data to db
func createGroup(onSccess completion:@escaping () -> Void) {
let inviteDispatchGroup = DispatchGroup()
let dataDispatchGroup = DispatchGroup()
let uid = FIRAuth.auth()?.currentUser?.uid
let name = String(uid!) + "_" + nameTextField.text!
// push invites
dataDispatchGroup.enter()
for invite in invites {
inviteDispatchGroup.enter()
let ref = FIRDatabase.database().reference().child("users").child(invite.id).child("invites")
ref.updateChildValues([name: nameTextField.text!]) { (error, ref) -> Void in
inviteDispatchGroup.leave()
}
}
inviteDispatchGroup.notify(queue: DispatchQueue.main, execute: {
dataDispatchGroup.leave()
})
// store picture
dataDispatchGroup.enter()
let storageRef = FIRStorage.storage().reference().child("profile_images").child("\(name).png")
if let uploadData = UIImagePNGRepresentation(profImage.resizeImage(targetSize: CGSize(width: 500, height: Int(500*(profImage.size.height/profImage.size.width))))) {
storageRef.put(uploadData, metadata: nil, completion: { (metadata, error) in
dataDispatchGroup.leave()
})
}
// store pet info
dataDispatchGroup.enter()
let petRef = FIRDatabase.database().reference().child("pets").child(name)
petRef.setValue(["mod":uid!, "name":nameTextField.text!, "members":[uid!]]) { (error, ref) -> Void in
dataDispatchGroup.leave()
}
// store user info
dataDispatchGroup.enter()
let userRef = FIRDatabase.database().reference().child("users").child(uid!).child("pets")
userRef.updateChildValues([name: true]) { (error, ref) -> Void in
dataDispatchGroup.leave()
}
dataDispatchGroup.notify(queue: DispatchQueue.main, execute: {
completion()
})
}
invitesDipatchGroup
is completed it's corresponding dataDispatchGroup
is left. leave()
. You have a potential bug, if the if let
doesn't have the value not optional. Fixed here:func createGroup(onSccess completion:@escaping () -> Void) {
[...]
// store picture
dataDispatchGroup.enter()
let storageRef = FIRStorage.storage().reference().child("profile_images").child("\(name).png")
if let uploadData = UIImagePNGRepresentation(profImage.resizeImage(targetSize: CGSize(width: 500, height: Int(500*(profImage.size.height/profImage.size.width))))) {
storageRef.put(uploadData, metadata: nil, completion: { (metadata, error) in
dataDispatchGroup.leave()
})
} else {
dataDispatchGroup.leave()
}
[...]
}