Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
接收Firebase快照时更新SwiftUI列表视图_Firebase_Firebase Realtime Database_View_Swiftui - Fatal编程技术网

接收Firebase快照时更新SwiftUI列表视图

接收Firebase快照时更新SwiftUI列表视图,firebase,firebase-realtime-database,view,swiftui,Firebase,Firebase Realtime Database,View,Swiftui,我的问题是,当我在firebase.com中更改字典时,我的SwiftUI列表没有更新。基本上,我打印出我已经读入了对象,并且它已经被添加到我的字典中,但是显示我的TODO的视图没有更新 ContentView.swift: struct ContentView: View { @EnvironmentObject var session: FirebaseSession var body: some View { NavigationView {

我的问题是,当我在firebase.com中更改字典时,我的SwiftUI列表没有更新。基本上,我打印出我已经读入了对象,并且它已经被添加到我的字典中,但是显示我的TODO的视图没有更新

ContentView.swift:

struct ContentView: View {

    @EnvironmentObject var session: FirebaseSession

    var body: some View {

        NavigationView {
            Group {
                if session.session != nil {
                    VStack {
                        NavigationLink(destination: NewTODOView()) {
                            Text("Add TODO")
                        }

                        **List{
                            ForEach(Array(self.session.todos.items.values), id: \.id) { todo in
                                NavigationLink(destination: TODODetailView(todo: todo)) {
                                    TODORowView(todo: todo)
                                }
                            }.onDelete(perform: session.delete)
                        }**
                    }
                    .navigationBarItems(trailing: Button(action: {
                        self.session.logOut()
                    }) {
                        Text("Logout")
                    })

                } else {
                    LoginView()
                    .navigationBarItems(trailing: Text(""))
                }
            }
            .navigationBarTitle(Text("TODO"))
            .padding()
        }
    }
}
FirebaseSession.swift:

@Published var session: User?
@Published var isLoggedIn: Bool?
@Published var todos: TODOS = TODOS(items: [:])

// Called by my initializer
func getTODOS() {
    ref.child("todoIDs").observe(.childAdded) { (snapshot) in
        TODO.makeTODO(ref: self.ref.child(snapshot.key), completion: { todo in
            if let todo = todo {
                self.todos.items[snapshot.key] = todo
            }
        })
    }
}
托多斯·斯威夫特:

class TODOS: ObservableObject {
    
    @Published var items: [String: TODO]
    
    init(itemsArr: [TODO]) {
        self.items = items
    }
}
托多·斯威夫特:

import SwiftUI
import FirebaseDatabase

class TODO: Identifiable, ObservableObject {
    
    var ref: DatabaseReference?
    var key: String
    var todo: String
    var isComplete: String
    var id: String
    @State var randomNumbers: [Int] = []
    
    static func makeTODO(ref: DatabaseReference, completion: @escaping (TODO?) -> ()) {
        ref.child("rest").observeSingleEvent(of: .value, with: { snapshot in
            completion(TODO(restSnapshot: snapshot))
        }, withCancel: { error in
            completion(nil)
            return
        })
    }
    
    init(todo: String, isComplete: String, key: String = "") {
        self.ref = nil
        self.key = key
        self.todo = todo
        self.isComplete = isComplete
        self.id = key
        self.randomNumbers = (0..<10).map { _ in .random(in: 1...20) }
    }
    
    init?(restSnapshot: DataSnapshot) {
        guard
            let value = restSnapshot.value as? [String: AnyObject],
            let todo = value["todo"] as? String,
            let isComplete = value["isComplete"] as? String
        else {
            return nil
        }
        self.ref = restSnapshot.ref.parent!
        self.key = self.ref!.key!
        self.todo = todo
        self.isComplete = isComplete
        self.id = self.key
        
        self.randomNumbers = []
        print(ref!.key!) // prints fine
        observe()
        
    }
    
    func observe() {
        ref?.child("randNums").queryLimited(toFirst: 5).observe(.value, with: { snapshot in
            guard
                let randNum = snapshot.value as? NSArray,
                let randNumArray = randNum as? [Int]
            else {
                print("guard not true")
                return
            }
            
            self.randomNumbers = randNumArray
            print("got \(randNumArray)") // also prints fine
            
        }, withCancel: { error in
            print(error)
        })
    }
    
    deinit {
        self.ref?.child("randNums").removeAllObservers()
    }
    
    func toAnyObject() -> Any {
        return [
            "rest": [
                "todo": todo,
                "isComplete": isComplete
            ],
            "randNums": randomNumbers
        ]
    }
}
导入快捷界面
导入FirebaseDatabase
类TODO:可识别、可观察的对象{
var ref:数据库引用?
变量键:字符串
var todo:字符串
var isComplete:String
变量id:String
@状态变量随机数:[Int]=[]
静态func makeTODO(ref:DatabaseReference,completion:@escaping(TODO?)->()){
ref.child(“rest”).observeSingleEvent(的值为:,其中:{snapshot in
完成(TODO(restSnapshot:snapshot))
},withCancel:{中出现错误
完成(无)
返回
})
}
init(todo:String,isComplete:String,key:String=”“){
self.ref=nil
self.key=key
self.todo=todo
self.isComplete=isComplete
self.id=key
self.randomNumbers=(0..Any{
返回[
“休息”:[
“待办事项”:待办事项,
“isComplete”:isComplete
],
“随机数”:随机数
]
}
}

还有一件事,如果我创建一个新的TODO对象,并将旧TODO对象的项赋予它,视图将更新。但我不想这样做,因为它不适用于其他项目,而且看起来很粗糙