5

ユーザーが自分のアプリケーションに新しいグループを作成するときに、データベースへの招待状やその他の情報をプッシュする必要があります。すべての情報がいつ送信されたかを把握するためにDispatch Groupsを使い始めました。ネストされたディスパッチグループSwift

招待状のディスパッチグループとすべてのデータのディスパッチグループを使用しようとしています。ここで私が持っているものだ:invitesDipatchGroupは、残っているdataDispatchGroup対応だ完了し

// 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() 
    }) 
} 

あなたが見ることができるように、。

私はディスパッチグループの新人です。これがこの種の仕事で取り組む正しいアプローチであるかどうか聞きたいと思います。

答えて

3

これは、非同期タスクトラッキングの非常に優れた方法です。

すべてのコードパスがleave()で覆われているかどうかを確認することが重要です。 if letの値がオプションでない場合、潜在的なバグがあります。

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() 
    } 
    [...] 
} 

一般に、使用するメソッドのすべてのコードパスですべての完了ブロックが必ず呼び出されるようにしてください。 Firebaseにはいつもバグがあるかもしれません。あるいは、それらのメソッドのドキュメンテーションで呼び出されていない補完についての何かがあるかもしれません。しかし、もう一度、これが行く方法です。

関連する問題