SwiftUI Firestore Așteptați pentru Încărcarea de Date

0

Problema

Am probleme cu preluarea Firestore getdocument de date înainte de a putea vizualiza sarcini. Știu că întoarcerea valorilor de la mai multe controale și probabil există o problemă cu modul de a ocupa asincron funcții.

Meu de trei variabile pe care încerc să o setați.

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

Aceasta este prima funcție care primește și stabilește numărul de participanți variabilă.

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

Această a doua funcție care primește și stabilește totală a răspuns variabil

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

Și eu folosesc această ultimă funcție pentru a compara cele două variabile și să se încarce în vedere dacă acestea sunt egale, altfel doar așteptați până când acestea sunt egale.

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
}

Aici este rezultatul Vedere că am încercat pentru a afișa pe baza datelor preluate.

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

Chiar dacă totalAnswered și numParticipants sunt egale atunci când punctul de vedere inițial afișat, showResults este întotdeauna setat la false. Dar atunci când datele se schimbă în cele din urmă devine setat la true dacă acestea devin egale din nou. Cred ca asta e din cauza API apel la firebase/firestore este de a lua timp și variabilele nu sunt stabilite înainte de a vizualiza sarcini. Nu vreau să folosesc asincron/așteaptă.

1

Cel mai bun răspuns

2

În prezent, codul executa self.getNumParticipants(..) independent de self.getRoom(roomId: roomId). Cu toate acestea, în checkShowResults, self.getRoom(roomId: roomId)depinde pe self.numParticipants care le primesc de la self.getNumParticipants(..). Deci, ai putea încerca cuiburi funcțiile de apeluri. Ceva de genul următorul cod:

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

În alte limbi

Această pagină este în alte limbi

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