SwiftUI 订阅 属性 更改为 EnvironmentObject

SwiftUI Subscribing to property change with EnvironmentObject

这是我的模型:

class Channel: Identifiable, Decodable, ObservableObject {
    
    var id = UUID()
    var channelId = ""
    var title = ""
    var thumbnail = ""
    @Published var thumbnailImage : UIImage?
    
    enum CodingKeys: String, CodingKey {
        
        //Keys not in the model
        case snippet
        case thumbnails
        case high
         
        //Keys in the model
        case channelId
        case title
        case thumbnail = "url"
    }
    
    required init (from decoder: Decoder) throws {
        
        let container =  try decoder.container(keyedBy: CodingKeys.self)
        let snippetContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .snippet)
        let thumbnailsContainer = try snippetContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .thumbnails)
        let highContainer = try thumbnailsContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .high)
        
        self.title = try snippetContainer.decode(String.self, forKey: .title)
        self.thumbnail = try highContainer.decode(String.self, forKey: .thumbnail)
        self.channelId = try snippetContainer.decode(String.self, forKey: .channelId)
    }
}
class ChannelStore: ObservableObject {    
    @Published var allChannels = [Channel]()
}

我有一个链接到 ChannelStore 的 EnvironmentObject,它都按预期工作。

问题是 属性 thumbnailImage 更改时我的视图需要更新。 (由于它来自网络调用,视图在调用 returns 之前生成,同时使用库存图像)。我尝试将 Published 属性 包装器添加到那个 属性 但它没有做任何事情。

在我看来我有:@EnvironmentObject var channelStore: ChannelStore

如何订阅由 EnvironmentObject 管理的 属性 变更?

编辑

建议将通道 class 更改为结构。我制作 class 的唯一原因是为了避免“无法分配给 属性:'channel' 是一个 'let' 常量:

for channel in channelStore.allChannels {
    networking.setThumbnail(channel: channel) { image in
        channel.thumbnailImage = image
    }
}

最终评论

我能够使用下面提供的答案解决整个问题,并将我的 for 循环更改为以下内容:

for (index, var channel) in channelStore.allChannels.enumerated() {
    networking.setThumbnail(channel: channel) { image in
        channel.thumbnailImage = image
        channelStore.allChannels[index] = channel
        print("Images LOADED")
    }
}

如果你能让你的 Channel 成为一个 struct:

struct Channel: Identifiable, Decodable { // <- replace `class` with `struct`
    ...
    var thumbnailImage : UIImage? // <- remove `@Published`
}

然后 thumbnailImage 的每次修改都会创建 Channel 对象的新副本并触发 ChannelStore 中的 @Published 属性:

class ChannelStore: ObservableObject {
    @Published var allChannels = [Channel]()
}