SwiftUI list показывает мои данные, затем показывает пустой список, используя ObservableObject для получения данных Firestore - PullRequest
1 голос
/ 21 марта 2020

Вот сценарий: Onappear мое представление вызывает метод getData моего класса ObservableObject. Во время отладки я вижу, что он получает данные и возвращает массив, как и ожидалось. Когда на симуляторе появляется мое изображение, данные кратко мигают в списке, затем список становится пустым. Я использую этот же шаблон в нескольких местах в моем приложении, и в некоторых случаях он работает (список отображается так, как должен), а в других он пропадает.

Я тестирую на симуляторах 13.0 и 13.3 из-за различные ошибки swiftUI, которые работают на одном или другом. Я думал, что это может быть из-за асинхронного c вызова Firestore, но я реализовал обработчики завершения. ЕСЛИ я изменяю ObservedObject на @State, то список отображается правильно, но при добавлении новых элементов он не обновляется sh.

Вот код для одного из примеров, который не работает:

Мой VIEW:

import SwiftUI
import Firebase 

struct ManagerListView: View {
    var circuitId: String
    @State private var isMgr:Bool = true //TODO: reset to false
    @EnvironmentObject var session : SessionStore
    @ObservedObject var managerArray = ManagerList()


    func deleteMgrDb(manager: Manager) {
        let docRef = Firestore.firestore().collection("circuits").document(circuitId).collection("managers").document(manager.id)

        docRef.delete { (error) in
            if error != nil {
                print(error!.localizedDescription)
            }
        }
    }
     var body: some View {
        List {
            ForEach(managerArray.managers) { i in

                Text("\(i.firstName) \(i.lastName)  \(i.phone)").deleteDisabled(!self.isMgr)
            }.onDelete { (indexset) in
                let manager = self.managerArray.managers[indexset.first!]
                print("Here \(self.managerArray.managers[indexset.first!])")
                //TODO:  Check if owner (can't remove owner) or maybe if at least one manager (then delete owner?)
                self.managerArray.managers.remove(atOffsets: indexset)
                self.deleteMgrDb(manager: manager)
            }.disabled(!isMgr)

        }.onAppear(perform: {
            self.managerArray.getData(forcircuitid: self.circuitId) { (error) in
                if error != nil {
                    //TODO: Return data error to user
                    print(error!.localizedDescription)
                }
                //TODO: isMgr
            }
        }).onDisappear(perform: {
             self.managerArray.stopMgrListListener()
        }).navigationBarItems(trailing: isMgr ?
            NavigationLink(destination: CircuitManagerAddView(circuitId: self.circuitId, currentmgrs: managerArray.managers), label: {
                Image(systemName: "plus")
            }): nil) //.disabled(!isMgr))
     }
}

Мой наблюдаемый класс:

class ManagerList: ObservableObject {
    @Published var managers = [Manager]()

    var listener: ListenerRegistration?

    func getData(forcircuitid: String, completion: @escaping (Error?)->Void) {

        let db = Firestore.firestore().collection("circuits").document(forcircuitid).collection("managers")

        self.managers.removeAll()

        listener = db.addSnapshotListener { (snapshot, error) in
            if error != nil {
                print(error!.localizedDescription)
                completion(error)
            }
            else {
                for i in snapshot!.documentChanges {
                    if i.type == .added {
                        let email  = i.document.get("email") as! String
                        let lastName = i.document.get("lastname") as! String
                        let firstName = i.document.get("firstname") as! String
                        let phone = i.document.get("phonenum") as! String

                        let manager = Manager(id: email, lastName: lastName, firstName: firstName, phone: phone)

                        self.managers.append(manager)

                        //TODO:  Changed
                    }
                }
                completion(nil)
            }
        }
    }

Для моих списков, которые работают, я использую в основном тот же код, за исключением изменения документов Firestore , элементы данных, имена переменных и т. д. c .. Они даже работают одинаково в отладчике, единственное отличие состоит в том, что одни работают и отображают список, а другие нет.

...