Вот сценарий: 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 .. Они даже работают одинаково в отладчике, единственное отличие состоит в том, что одни работают и отображают список, а другие нет.