SwiftUI Firestore Čekat na Načítání Dat

0

Otázka

Mám potíže při načítání Firestore getdocument dat před prohlížení zatížení. Vím, že se to vrací hodnoty z více kontroly a tam je asi problém s tím, jak jsem zvládnout asynchronní funkce.

Moje tři proměnné, které se snažím nastavit.

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

Toto je první funkce, která získá a nastaví počet účastníků proměnné.

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

Tato druhá funkce, která získá a nastaví celkový odpověděl proměnné

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

A pak jsem pomocí poslední funkce, chcete-li porovnat dvě proměnné a načíst pohled, pokud jsou stejné, jinak jen čekat, až budou rovné.

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
}

Zde se Výsledky Zobrazit, že jsem se snažil zobrazit vychází z načtené údaje.

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

I když totalAnswered a numParticipants jsou rovné při pohledu zpočátku zobrazí, showResults je vždy nastavena na hodnotu false. Ale když data změny, to nakonec dostane nastavena na hodnotu true, pokud se stanou rovné znovu. Myslím, že to je proto, že volání API firebase/firestore je čas a proměnné nejsou nastaveny před prohlížení zatížení. Nemám opravdu chcete použít async/await.

1

Nejlepší odpověď

2

V současné době váš kód spustit self.getNumParticipants(..) nezávisle self.getRoom(roomId: roomId). Nicméně v checkShowResults, self.getRoom(roomId: roomId)záleží na self.numParticipants to, že se dostanete z self.getNumParticipants(..). Takže můžete zkusit vnoření funkce volání. Něco jako následující kód:

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

V jiných jazycích

Tato stránka je v jiných jazycích

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