SwiftUI - 将托管对象上下文传递给模型
SwiftUI - passing managed object context to model
使用 @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")
}
}
您不能在视图中使用 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
}
}
}
使用 @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")
}
}
您不能在视图中使用 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
}
}
}