【问题标题】:How to pass/get Core Data context in SwiftUI MVVM ViewModel?如何在 SwiftUI MVVM ViewModel 中传递/获取核心数据上下文?
【发布时间】:2021-01-05 15:23:24
【问题描述】:

上下文

要对核心数据对象执行操作,需要托管对象上下文managedObjectContext。通过在选中“使用核心数据”选项中生成项目时,通过环境变量将上下文传递到视图中,选中“使用核心数据”选项(请参阅下文)。一个相关的问题是Why does Core Data context object have to be passed via environment variable?

let contentView = MainView().environment(\.managedObjectContext, context)

但是,当我尝试将 context 传递到视图模型时,它会抱怨以下内容

不能在属性初始化器中使用实例成员“上下文”;属性初始化器在“self”可用之前运行

struct MainView: View {
    @Environment(\.managedObjectContext) var context
    
    // Computed property cannot be used because of the property wrapper
    @ObservedObject var viewModel = ViewModel(context: context)
}

class ViewModel: ObservableObject {
    var context: NSManagedObjectContext
}

添加init() 来初始化视图内的视图模型会导致不同的错误导致构建失败。

无法生成表达式诊断;请提交错误报告

    init() {
        self.viewModel = ViewModel(context: context)
    }

问题

那么我如何在视图模型中使用/获取/传递上下文呢?在视图模型中获取上下文的更好方法是什么?

【问题讨论】:

  • 例如,您可以为您的视图创建一个 init() 并将其设置在那里,但老实说,如果您使用 MVVM,您的视图应该可以访问 NSManagedObjectContext 实例吗?
  • SceneDelegate 的上下文引用似乎是唯一的来源,还有其他方法,我可以在 View Model 中获取上下文吗?
  • 这可能对你有帮助:stackoverflow.com/q/61571960/8697793
  • 您有一个 init 方法,它将视图模型作为视图中的参数,而不是在视图中实例化视图模型,这使您的代码更容易测试,并且两者之间的耦合更弱。

标签: swift core-data mvvm swiftui


【解决方案1】:

这是你的场景

let contentView = MainView(context: context)          // << inject
        .environment(\.managedObjectContext, context)

struct MainView: View {
    @Environment(\.managedObjectContext) var context

    @ObservedObject private var viewModel: ViewModel // << declare

    init(context: NSManagedObjectContext) {
        self.viewModel = ViewModel(context: context)   // initialize
    }
}

【讨论】:

  • 每次呈现视图时都会调用 init 函数。可能这个视图MainVeiw 只出现一次,但一般来说这会导致 ViewModel 被多次初始化。
【解决方案2】:

CoreData 上下文可以通过AppDelegate 对象获取。

import SwiftUI

class ViewModel: ObservableObject {
    var context: NSManagedObjectContext
    
    init() {
        let app = UIApplication.shared.delegate as! AppDelegate
        self.context = app.persistentContainer.viewContext
    }
}

参考,https://kavsoft.dev/Swift/CoreData/

【讨论】:

    猜你喜欢
    • 2018-12-29
    • 2022-07-29
    • 1970-01-01
    • 2022-07-28
    • 2020-08-13
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多