我有一个 MacOS 应用程序,允许在多个 Windows 中声明。
import SwiftUI
import CoreData
@main
struct TM_window_TestApp: App {
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ItemListView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
}
struct PersistenceController {
static let shared = PersistenceController()
let container: NSPersistentContainer
init() {
container = NSPersistentContainer(name: "TM_window_Test")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
}
}
extension Item {
public var name: String
{ get
{ return name_ ?? "NONAME"
}
set(newName)
{ name_ = newName
//objectWillChange.send()
}
}
}
我希望窗口在同一个 ManagedObjextContext 上工作。
在 ItemListView() 中,我列出了所有项目。
添加新项目时,它仅显示在按下“加号”按钮的窗口中,而不显示在其他窗口中。
为什么其他 Windows 中的@FetchRequest 没有更新?
我怎样才能强制更新?
struct ItemListView: View {
@StateObject var listProperties = ListProperties()
@Environment(\.managedObjectContext) private var moc
@FetchRequest( sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)])
private var items: FetchedResults<Item>
var body: some View {
VStack {
List(items, id: \.self, selection: $listProperties.selectedItem ) { item in
Text("\(item.name) at \(item.timestamp!, formatter: itemFormatter)")
}
.toolbar {
#if os(iOS)
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
#endif
ToolbarItem {
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
}
}
Button("Delete All Items"){deleteAllItems()}
}
}
private func addItem() {
let newItem = Item(context: moc)
newItem.timestamp = Date()
do {
try moc.save()
moc.refresh(newItem, mergeChanges: true)
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
private func deleteAllItems () {
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Item")
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
deleteRequest.resultType = .resultTypeObjectIDs
do {
let result = try moc.execute(deleteRequest) as? NSBatchDeleteResult
let changes: [AnyHashable: Any] = [NSDeletedObjectsKey: result?.result as? [NSManagedObjectID] ?? []]
NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [moc])
} catch let error as NSError {
fatalError("DELETING ALL \("ITEM") failed: \(error)")
}
}
}
private let itemFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .medium
return formatter
}()