更新视图的自定义属性包装器 代码11.3,Swift 5.1.3

更新视图的自定义属性包装器 代码11.3,Swift 5.1.3,swift,firebase,firebase-realtime-database,swiftui,property-wrapper,Swift,Firebase,Firebase Realtime Database,Swiftui,Property Wrapper,我目前正在尝试创建一个自定义属性包装器,它允许我将变量链接到Firebase数据库。在执行此操作时,为了使其更新视图,我首先尝试使用@ObservedObject@Bar var foo=[]。但我得到一个错误,即不支持多个属性包装器。下一件我尝试做的事情,老实说是理想的,就是尝试让我的自定义属性包装器在被更改时更新视图本身,就像@State和@ObservedObject一样。这既避免了需要向下两层访问底层值,也避免了使用嵌套属性包装器。为此,我查看了SwiftUI文档,发现它们都实现了Dyn

我目前正在尝试创建一个自定义属性包装器,它允许我将变量链接到Firebase数据库。在执行此操作时,为了使其更新视图,我首先尝试使用
@ObservedObject@Bar var foo=[]
。但我得到一个错误,即不支持多个属性包装器。下一件我尝试做的事情,老实说是理想的,就是尝试让我的自定义属性包装器在被更改时更新视图本身,就像
@State
@ObservedObject
一样。这既避免了需要向下两层访问底层值,也避免了使用嵌套属性包装器。为此,我查看了SwiftUI文档,发现它们都实现了
DynamicProperty
协议。我也尝试过使用它,但失败了,因为我需要能够从我的Firebase数据库观察器中更新视图(调用
update()
),这是因为
.update()
正在发生变化

以下是我目前的尝试:

导入快捷界面
进口火基
导入CodableFirebase
进口联合收割机
@房地产经纪人
最终类DatabaseBackedArray:ObservableObject,其中元素:可编码和可识别{
typealias ObserverHandle=UInt
typealias Action=RealtimeDatabase.Action
typealias事件=RealtimeDatabase.Event
私有(集合)变量引用:DatabaseReference
私有变量currentValue:[元素]
私有变量ChildAddedObjerHandle:ObserverHandle?
private var childChangedObserverHandle:ObserverHandle?
private var childRemovedObserverHandle:ObserverHandle?
private var childAddedActions:[操作]=[]
private var childChangedActions:[操作]=[]
private var childRemovedActions:[操作]=[]
init(wrappedValue:[Element],upath:KeyPath,events:Event=.all,
操作:[操作]=[]){
currentValue=wrappedValue
reference=RealtimeDatabase()[keyPath:path]。引用
行动中的行动{
如果action.event.contains(.childAdded){
childAddedActions.append(操作)
}
如果action.event.contains(.childChanged){
childChangedActions.append(操作)
}
如果action.event.contains(.childRemoved){
childRemovedActions.append(操作)
}
}
if events.contains(.childAdded){
ChildAddedObjerHandle=reference.observe(.childAdded){中的快照
guard let value=snapshot.value,let decodedValue=try?FirebaseDecoder().decode(Element.self,from:value)else{
fatalError(“无法从Firebase解码值。”)
}
self.objectWillChange.send()
self.currentValue.append(解码值)
self.childAddedActions.forEach{$0.action(&self.currentValue)}
}
}
如果events.contains(.childChanged){
childChangedObserverHandle=reference.observe(.childChanged){中的快照
guard let value=snapshot.value,let decodedValue=try?FirebaseDecoder().decode(Element.self,from:value)else{
fatalError(“无法从Firebase解码值。”)
}
guard let changeIndex=self.currentValue.firstIndex(其中:{$0.id==decodedValue.id})else{
返回
}
self.objectWillChange.send()
self.currentValue[changeIndex]=解码值
self.childChangedActions.forEach{$0.action(&self.currentValue)}
}
}
if events.contains(.childRemoved){
childRemovedObserverHandle=reference.observe(.childRemoved){中的快照
guard let value=snapshot.value,let decodedValue=try?FirebaseDecoder().decode(Element.self,from:value)else{
fatalError(“无法从Firebase解码值。”)
}
self.objectWillChange.send()
self.currentValue.removeAll{$0.id==decodedValue.id}
self.childRemovedActions.forEach{$0.action(&self.currentValue)}
}
}
}
private func setValue(到值:[元素]){
guard let encodedValue=try?FirebaseEncoder()。encode(currentValue)else{
fatalError(“无法将值编码到Firebase。”)
}
参考设置值(编码值)
}
var wrappedValue:[元素]{
得到{
返回电流值
}
设置{
self.objectWillChange.send()
设置值(至:新值)
}
}
var projectedValue:绑定{
返回绑定(获取:{
返回self.wrappedValue
}){newValue in
self.wrappedValue=newValue
}
}
var hasActiveObserver:Bool{
返回childAddedObjerHandle!=nil | | childChangedObserverHandle!=nil | | childRemovedObserverHandle!=nil
}
var HASCHILDADEDOBSERVER:Bool{
返回ChildAddedObjectServerHandle!=nil
}
var hasChildChangedObserver:Bool{
返回childChangedObserverHandle!=nil
}
var hasChildRemovedObserver:Bool{
返回childRemovedObserverHandle!=nil
}
func ConnectObserver(用于事件:事件){
如果event.contains(.childAdded)&&childAddedObserverHandle==nil{
ChildAddedObjerHandle=reference.observe(.childAdded){中的快照
guard let value=snapshot.value,let decodedValue=try?FirebaseDecoder().decode(Element.self,from:value)else{
fatalError(“无法从Firebase解码值。”)
}
self.objectWillChange.send()
self.currentValue.append(解码值)
self.childAddedActions.forEach{$0.action(&self.currentValue)}