5

Gdy użytkownik tworzy nową grupę w mojej aplikacji, muszę wysłać zaproszenia do bazy danych, a także inne informacje. Zacząłem korzystać z grup wysyłkowych, aby śledzić, kiedy wszystkie informacje zostaną wysłane, więc mogę odrzucić widok.Zagnieżdżone grupy wysyłkowe Swift

Próbuję użyć grupy wysyłkowej dla zaproszeń i innej grupy wysyłkowej dla wszystkich danych. Oto co mam:

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

Jak widać, gdy invitesDipatchGroup jest zakończona to odpowiada dataDispatchGroup pozostało.

Jestem nowy w grupach wysyłkowych i chcę usłyszeć, czy jest to właściwe podejście do wykonywania tego rodzaju zadań.

Odpowiedz

3

Jest to bardzo dobre podejście do śledzenia zadań asynchronicznych.

Ważne jest sprawdzenie, czy wszystkie ścieżki kodowe są pokryte leave(). Masz potencjalnego błędu, jeśli if let nie ma wartości nie jest opcjonalna. Naprawiono tutaj:

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

Generalnie zawsze upewnij się, że wszystkie bloki zakończenia są wywoływane we wszystkich ścieżkach kodu używanych metod. Zawsze może występować błąd w Firebase lub może się zdarzyć, że coś takiego w dokumentacji tych metod nie zostanie wywołane. Ale znowu, to jest droga.