Я нашел решение этой проблемы, когда вспомнил, что класс может подписаться на изменения в другом классе с волхвами c из Combine
. Поэтому, если бы я мог подписать класс RoleStore
на изменения в SkillStore
, тогда RoleStore
мог бы обновлять и удалять навык в его ролях, когда пользователь удаляет навык.
Для этого RolesStore
необходимо иметь ссылку на SkillStore
:
import SwiftUI
import PlaygroundSupport
var skillStore = SkillStore(skills: MySkills.skills())
var roleStore = RoleStore(roles: MyRoles.roles(), skillStore: skillStore)
struct ModelsView: View {
@ObservedObject var skillStore: SkillStore
@ObservedObject var roleStore: RoleStore
....
SkillStore
обновляется с помощью PassthroughSubject
, который отправляет удаленный навык (deletedPublisher
):
import Foundation
import Combine
public final class SkillStore: ObservableObject {
@Published public var skills: [Skill] = [] {
didSet {
let oldSkills = Set(oldValue)
let uniqueSet = oldSkills.subtracting(self.skills)
if let deletedSkill = uniqueSet.first {
deletedPublisher.send(deletedSkill)
}
}
}
private var cancellables: Set<AnyCancellable> = []
let deletedPublisher = PassthroughSubject<Skill, Never>()
public init(skills: [Skill]) {
self.skills = skills
}
public func delete(skills: [Skill]) {
for skill in skills {
if let index = self.skills.firstIndex(where: { $0 == skill }) {
self.skills.remove(at: index)
}
}
}
}
и наконец RoleStore
удаляет удаленный навык из всех ролей, имеющих этот навык:
import Foundation
import Combine
import SwiftUI
public final class RoleStore: ObservableObject {
@Published public var roles: [Role] = []
@ObservedObject var skillStore: SkillStore
private var cancellables: Set<AnyCancellable> = []
public init(roles: [Role], skillStore: SkillStore) {
self.roles = roles
self.skillStore = skillStore
self.skillStore.deletedPublisher.sink { skill in
for roleIndex in self.roles.indices {
let skills = self.roles[roleIndex].skills.filter { $0 != skill }
self.roles[roleIndex].skills = skills
}
}
.store(in: &cancellables)
}
}
Я обновил игровую площадку с изменениями.