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ă.