SwiftUI Подписка на изменение свойств с помощью 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]()
}

У меня есть EnvironmentObject, связанный с ChannelStore, и все работает, как ожидалось.

Проблема в том, что мое представление необходимо обновить при изменении свойства thumbnailImage. (Так как это из сетевого вызова, представление создается до того, как вызов возвращается, и в то же время использует стоковое изображение). Я попытался добавить к этому свойству оболочку свойства Published, но ничего не вышло.

На мой взгляд, у меня есть: @EnvironmentObject var channelStore: ChannelStore

Как подписаться на изменение свойства, которым управляет EnvironmentObject?

редактировать

Было предложено изменить класс 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")
                        }
                    }

1 ответ

Решение

Если вы можете сделать свой Channelструктура:

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

Тогда каждая модификация thumbnailImage создаст новую копию Channel объект и вызвать @Published собственность в ChannelStore:

class ChannelStore: ObservableObject {
    @Published var allChannels = [Channel]()
}
Другие вопросы по тегам