Mám problém pri získavaní Firestore getdocument údajov pred zobrazenie zaťaženia. Viem, že to vracia hodnoty z viacerých kontroly a tam je asi problém s tým, ako zvládam asynchrónne funkcie.
Moje tri premenné, ktoré snažím sa nastaviť.
@Published var numParticipants = 0
@Published var totalAnswered = 0
@Published var showResults = false
Toto je prvá funkcia, ktorá dostane a nastaví počet účastníkov premennej.
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)
}
}
}
}
Táto druhá funkcia, ktorá dostane a stanovuje celkový odpovedal premennej
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 potom som používať tento posledný funkcia porovnať dve premenné a zaťaženie názor, ak sú rovné, inak jednoducho počkajte, kým sú rovnaké.
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
}
Tu je Results, ktorý sa snažím zobrazenie založené mimo načítané ú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)
}
}
Aj v prípade, ak totalAnswered a numParticipants sú rovnaké, ak chcete zobraziť najprv zobrazí, showResults je vždy nastavený na hodnotu false. Ale keď zmeny údajov sa nakoniec dostane nastaviť na hodnotu true, ak sa stanú rovné znova. Myslím, že je to preto, že volanie API na firebase/firestore je čas a premenné nie sú nastavené pred zobrazenie zaťaženia. Nemám naozaj chcete použiť async/čakajú.