SwiftUI - 将托管对象上下文传递给模型

Posted

技术标签:

【中文标题】SwiftUI - 将托管对象上下文传递给模型【英文标题】:SwiftUI - passing managed object context to model 【发布时间】:2020-08-24 16:06:44 【问题描述】:

使用 @Environment 变量将托管对象上下文传递给 SwiftUI 中的视图非常简单。但是在模型和视图模型中获得相同的上下文,并没有那么多。这是我尝试过的:

我在视图模型中创建了一个名为 context 的属性。在视图中,我懒惰地传递托管对象上下文。问题是现在当我从视图调用视图模型的方法时出现错误 - “不能对不可变值使用变异 getter:'self' 是不可变的”。该方法在我添加上下文之前有效,为什么它停止工作?而且,更重要的是,我该如何让它发挥作用?!

型号:

struct Model 

   //use fetch request to get users

   func checkLogin(username: String, password: String) 
      for user in users  
        if username == user.userEmail && password == user.password 
            return true
        
    
    return false
   

查看模型:

class ViewModel 
   var context: NSManagedObjectContext
   private var model = Model()

   init(context: NSManagedObjectContext) 
      self.context = context 
   

   func checkLogin(username: String, password: String) -> Bool 
      model.checklogin(username: username, password: password)
   

最后是视图:

struct LoginView: View 
   @Environment(\.managedObjectContext) var moc
   lazy var viewModel = ViewModel(context: moc) 

    //Login form
    
    Button(action: 
       if self.viewModel.checkLogin(username: self.email, password: self.password)  
       //ERROR: Cannot use mutating getter on immutable value: 'self' is immutable
          //allow login
       
    ) 
        Text("login")
    

【问题讨论】:

【参考方案1】:

您不能在 View 中使用 lazy var,因为它是不可变的。这是解决您的情况的可能方法

class ViewModel 
   var context: NSManagedObjectContext?
   private var model = Model()

   init(context: NSManagedObjectContext? = nil) 
      self.context = context
   

   func checkLogin(username: String, password: String) -> Bool 
      return model.checkLogin(username: username, password: password)
   


struct LoginView: View 
   @Environment(\.managedObjectContext) var moc

   private let viewModel = ViewModel()   // no context yet here, so just default

    //Login form
    var body: some View 
        Button(action: 
           if self.viewModel.checkLogin(username: self.email, password: self.password) 
              //allow login
           
        ) 
            Text("login")
        
        .onAppear 
            self.viewModel.context = moc  // << set up context here
        

    

【讨论】:

这可行,但由于视图模型在没有上下文的情况下无法工作,我们不应该有一个空的初始化程序来允许这样做。我认为 Apple 很快就会引入一种机制,将环境变量从 SwiftUI 视图传递给自定义类型(如视图模型)。

以上是关于SwiftUI - 将托管对象上下文传递给模型的主要内容,如果未能解决你的问题,请参考以下文章

如何将上下文对象传递给 NSValueTransformer

使用选项卡控制器传递托管对象上下文

如何将对象上下文传递给 jQuery.ajax JSONP 回调?

将上下文传递给许多方法是否正常?

最好将 prisma 对象通过上下文传递给解析器还是直接使用它?

如何将表单视图作为 django 中的上下文传递给另一个视图?