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

SwiftUI-将托管对象上下文传递给模型,swiftui,nsmanagedobjectcontext,Swiftui,Nsmanagedobjectcontext,使用@Environment变量将托管对象上下文传递给SwiftUI中的视图非常简单。但是将相同的上下文添加到模型和视图模型中,就不那么多了。以下是我尝试过的: 我在视图模型中创建了一个名为context的属性。在视图中,我懒洋洋地传递托管对象上下文。问题是,现在我在从视图调用视图模型的方法时遇到了一个错误——“不能对不可变值使用mutating getter:‘self’是不可变的”。在我添加上下文之前,该方法已经工作了,那么为什么它停止工作了呢?而且,更重要的是,我如何让它工作 型号: st

使用@Environment变量将托管对象上下文传递给SwiftUI中的视图非常简单。但是将相同的上下文添加到模型和视图模型中,就不那么多了。以下是我尝试过的:

我在视图模型中创建了一个名为context的属性。在视图中,我懒洋洋地传递托管对象上下文。问题是,现在我在从视图调用视图模型的方法时遇到了一个错误——“不能对不可变值使用mutating 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")
    }
}

不能在视图中使用
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
        }

    }
}
类视图模型{
变量上下文:NSManagedObjectContext?
私有var模型=模型()
init(上下文:NSManagedObjectContext?=nil){
self.context=context
}
func checkLogin(用户名:String,密码:String)->Bool{
返回模型。检查登录(用户名:用户名,密码:密码)
}
}
结构逻辑视图:视图{
@环境(\.managedObjectContext)变量moc
private let viewModel=viewModel()//这里还没有上下文,所以只使用默认值
//登录表单
var body:一些观点{
按钮(操作:{
if self.viewModel.checkLogin(用户名:self.email,密码:self.password){
//允许登录
}
}) {
文本(“登录”)
}
奥纳佩尔先生{

self.viewModel.context=moc/不能在视图中使用
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
        }

    }
}
类视图模型{
变量上下文:NSManagedObjectContext?
私有var模型=模型()
init(上下文:NSManagedObjectContext?=nil){
self.context=context
}
func checkLogin(用户名:String,密码:String)->Bool{
返回模型。检查登录(用户名:用户名,密码:密码)
}
}
结构逻辑视图:视图{
@环境(\.managedObjectContext)变量moc
private let viewModel=viewModel()//这里还没有上下文,所以只使用默认值
//登录表单
var body:一些观点{
按钮(操作:{
if self.viewModel.checkLogin(用户名:self.email,密码:self.password){
//允许登录
}
}) {
文本(“登录”)
}
奥纳佩尔先生{

self.viewModel.context=moc//可以工作,但由于视图模型在没有上下文的情况下无法工作,我们不应该有一个空的初始值设定项来允许这样做。我认为苹果很快就会引入一种机制,将环境变量从SwiftUI视图传递到自定义类型(如视图模型)。这是可行的,但由于视图模型在没有上下文的情况下无法工作,因此我们不应该有一个空的初始值设定项来实现这一点。我认为苹果将很快引入一种机制,将环境变量从SwiftUI视图传递到自定义类型(如视图模型)。