首页 > 解决方案 > 组合 - 将类发布的属性分配给数据模型结构中的属性

问题描述

我收到一个错误 -Key path value type 'ReferenceWritableKeyPath<Foo, [Bar]?>' cannot be converted to contextual type 'WriteableKeyPath<Foo, [Bar]?>'尝试将存储库类中的某些内容发布到我的主要数据模型结构的实例中,但不确定如何处理此错误。

情况

我有一个“Foo”,其中可以加载一个“Bars”数组,它们作为我数据库中的单独集合加载到单独的存储库中。

我有一个FooViewModel将一个 foo 视为已发布属性,然后我将一个注入barRepository到该 ViewModel 中,以在用户按下按钮时加载与该 foo 相关联的所有栏。

当用户按下此按钮时,我的 viewModel 有一个subscribeToBarActions()被调用,并且此函数尝试订阅barsPublisher存储库中的变量,并将它们分配给barsViewModel 中 foo 对象中的属性。

我的代码

当用户单击 Foo 中的“Load Bars”按钮时,将调用 ViewModel 中的此方法(错误发生在该.assign(...)行)。我的目标是订阅 bar 数组,并将它们映射到 ViewModel 中 foo 对象中的 bar 属性:

    func subscribeToFooBars() {
        self.fooBarRepository.barPublisher
            .map { bars in
                .map { bar in
                    Bar.self
                }
            }
            .assign(to: \.bars, on: self.foo)
            .store(in: &cancellables)
        
        self.fooBarRepository.loadData()
    }

这是 Foo 结构,其中有 bar 作为变量 - 当我们最初加载 Foo 的实例时,bar 被实例化为 nil 或空数组(我没有充分的理由做一个与另一个对现在)。

struct Foo: Codable, Identifiable, Equatable {
    // Identifiers
    @DocumentID var id: String?
    var title: String
    var description: String?
    var bars: [Bar]?

fooBarRepository只是有这个发布者,它应该加载和存储发布到 ViewModel 的栏,旨在将它们保存到栏属性

class BarRepository: ObservableObject, BarStoreType {
    
    @Published var bars = [Bar]()
    var barsPublished: Published<[Bar]> { _bars }
    var barsPublisher: Published<[Bar]>.Publisher { $bars }

foo在 ViewModel 中的属性已发布,但该bars结构内的属性未发布。我想知道这是否可能是问题,或者它是否可能与存储库是引用类型而 Foo 结构是值类型的事实有关。关于是什么原因造成的任何想法?

标签: swiftcombine

解决方案


再研究一下,看起来这肯定是因为我的数据模型中的 Bar 属性在一个结构中,而我的存储库中的 Bar 属性在一个类中。

有关更多信息,请参阅Sundell 的这篇 Swift 文章

所以为了解决这个问题,我意识到我实际上并不需要将 Bars 数组包含在我的 Foo 中(如果不是这样可能会更容易,因为我不希望将数据保存到数据库中的 Foo 实例中)。我只需要确保它们在同一个 ViewModel 中。

所以我添加@Published var bars: [Bar]?到我的 ViewModel,现在我在我的存储库中将订阅直接分配给 ViewModel 中的那个变量。我不需要将它们实际链接到 的相同数据模型实例下Foo,只要它们位于相同的FooCellViewModel.

    func subscribeToFooBars() {
        self.fooBarRepository.BarPublisher
            .compactMap { $0 }
            .assign(to: \.bars, on: self)
            .store(in: &cancellables)
    }

推荐阅读