如果你有
@Environment(\.managedObjectContext) var context
@ObservedObject var model: SomeType
在视图的顶部
您可以使用
.task(id: model.hasChanges) {
guard model.hasChanges else {return}
try? context.save()
}
只要有变化,它就会保存下来。
你可以把这个放在
ViewModifier
以便在您想要自动保存的任何位置轻松访问。
import SwiftUI
import CoreData
struct SimpleItemListView: View {
@FetchRequest( sortDescriptors: []) var items: FetchedResults<SimpleItem>
var body: some View {
List(items) { item in
Text(item.name ?? "")
.autoSave(item)
}
}
}
#Preview {
SimpleItemListView()
.environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
}
extension View {
func autoSave<MO>(_ object: MO) -> some View where MO: NSManagedObject {
modifier(AutoSave(object: object))
}
}
struct AutoSave<MO>: ViewModifier where MO: NSManagedObject {
@Environment(\.managedObjectContext) var managedObjectContext
@ObservedObject var object: MO
@State private var alert: (isPresented: Bool, error: LocalError?) = (false, nil)
func body(content: Content) -> some View {
content
.alert(isPresented: $alert.isPresented, error: alert.error, actions: {
Button("Ok") {
alert = (false, nil)
}
})
.task(id: object.hasChanges) {
guard object.hasChanges else {return}
do {
try await managedObjectContext.perform {
try managedObjectContext.save()
}
} catch {
alert = (true, LocalError.error(error))
}
}
}
private enum LocalError: LocalizedError {
case error(Error)
var errorDescription: String?{
switch self {
case .error(let error):
return error.localizedDescription
}
}
}
}