SwiftUI Firestore Attendre pour le Chargement des Données

0

La question

Je vais avoir de la difficulté à extraire Firestore getdocument données avant le point de vue des charges. Je sais qu'il renvoi de valeurs à partir de multiples vérifications et il y a probablement un problème avec la façon dont je gère les fonctions asynchrones.

Mes trois variables que je suis en train de mettre.

@Published var numParticipants = 0
@Published var totalAnswered = 0
@Published var showResults = false

C'est la première fonction qui obtient et définit le nombre de participants variable.

func getRoom(roomId: String, onSuccess: @escaping(_ room: Room) -> Void) {
    DB.collection("Rooms").document(roomId).addSnapshotListener { document, error in
        DispatchQueue.main.async {
            if let dict = document?.data() {
                guard let decodeRoom = try? Room.init(fromDictionary: dict) else { return }
                onSuccess(decodeRoom)
            }
        }
    }
}

La deuxième fonction qui obtient et définit le total répondu variable

func getNumParticipants(roomId: String, onSuccess: @escaping(_ numParticipants: Int) -> Void) {

    DB.collection("RoomsParticipants").document(roomId).collection("Participants").getDocuments { snapshot, error in
        DispatchQueue.main.async {
            if let error = error {
                print(error.localizedDescription)
                return
            } else {
                onSuccess(snapshot!.count)
            }
        }
    }
}

Puis-je utiliser cette dernière fonction pour comparer deux variables et de charger la vue si elles sont égales, sinon juste attendre jusqu'à ce qu'ils sont égaux.

func checkShowResults(roomId: String) {
    isLoading = true
    
    self.getNumParticipants(roomId: roomId) { numParticipants in
        print("Number of docs: \(numParticipants)")
        DispatchQueue.main.async {
            self.numParticipants = numParticipants
        }
    }
    
    self.getRoom(roomId: roomId) { room in
        print("Total answered: \(room.totalAnswered)")
        DispatchQueue.main.async {
            self.totalAnswered = room.totalAnswered
            if self.totalAnswered == self.numParticipants {
                self.showResults = true
            }
        }
    }
    
    isLoading = false
}

Voici la Vue des Résultats que j'essaie d'afficher basés sur les données extraites.

struct ResultsView: View {

@StateObject var resultsViewModel = ResultsViewModel()
var roomId: String

var body: some View {
    VStack {
        if !resultsViewModel.showResults {
                VStack {
                    ProgressView()
                    Text("Waiting for all participants \nto finish answering...")
                }
            } else {
                ShowResultsView()
                }
            }
        }
    }.navigationBarHidden(true)
    .onAppear {
        resultsViewModel.checkShowResults(roomId: roomId)
    }
}

Même si le totalAnswered et numParticipants sont égales lorsque la vue affichée au départ, résultats des concours d'élevage est toujours défini sur false. Mais lors de la modification des données qu'il obtient finalement la valeur true si ils deviennent égaux à nouveau. Je pense que c'est parce que l'appel de l'API de firebase/firestore est de prendre le temps et les variables ne sont pas définies avant le point de vue des charges. Je n'ai pas vraiment envie d'utiliser async/await.

1

La meilleure réponse

2

Actuellement votre code à exécuter self.getNumParticipants(..) indépendamment de self.getRoom(roomId: roomId). Toutefois, dans checkShowResults, self.getRoom(roomId: roomId)dépend sur self.numParticipants que vous obtenez à partir de self.getNumParticipants(..). Donc, vous pourriez essayer de nidification vos appels de fonctions. Quelque chose comme le code suivant:

func checkShowResults(roomId: String) {
    self.isLoading = true
    
    self.getNumParticipants(roomId: roomId) { numParticipants in
        print("Number of docs: \(numParticipants)")
        DispatchQueue.main.async {
            self.numParticipants = numParticipants
            
            // get the room after the numParticipants has been set
            self.getRoom(roomId: roomId) { room in
                print("Total answered: \(room.totalAnswered)")
                DispatchQueue.main.async {
                    self.totalAnswered = room.totalAnswered
                    if self.totalAnswered == self.numParticipants {
                        self.showResults = true
                        self.isLoading = false
                    }
                }
            }
            
        }
    }
2021-11-22 03:36:51

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................