ARTICLE AD BOX
The basis for this is that I have an app where I am modifying a database using a simple Model: Record.
If I insert 10 records, and perform modelContext.save() I receive the notification (ModelContext.didSave) after I perform the save.
If I delete records, tand perform modelContext.save() there is no notification at all.
If I insert 10 records, and perform modelContext.save() I receive the notification (ModelContext.didSave) after I perform the save. However, the notification I receive after the save only shows the 10 (new) inserted records, and 0 deleted records.
Sample code:
extension ModelContext { static func subscribeForNotifications( printChanges: Bool = false, block: @Sendable @escaping (NotificationCenter.Notifications.Iterator.Element) -> Void ) -> Task<Void, Never> { let center = NotificationCenter.default let notificationName = ModelContext.didSave return Task.detached(priority: .userInitiated) { for await notification in center.notifications(named: notificationName) { block(notification) } } } } func insert10(modelContext: ModelContext) { Task.detached(priority: .userInitiated) { (1...10).forEach { let record = Record(id: UUID(), title: "Record \($0)") context.insert(record) } try! context.save() } } // One at a time func removeAllRecords(context: ModelContext) { let descriptor = FetchDescriptor<Record>() Task.detached(priority: .userInitiated { try context.fetch(descriptor) .forEach { context.delete($0) } } try context.save() } } // More effecient func removeEfficiently(context: ModelContext) { try context.delete(model: Record.self) try context.save() } func subscribeForNotifications() { notificationTask = ModelContext .subscribeForNotifications(printChanges: true) { _ in print("Received notification") Task { @MainActor in await self.reload() } } }Note: This code was extracted from a larger project. Threading is not a concern here, as everything is actually done through @ModelActor but showing all those redirections is confusing.
The issue is that when I call these functions in the order presented:
subscribeForNotifications() insert10(context: modelContext) removeAllRecords(context: modelContext) insert10(context: modelContext) removeEfficiently(context: modelContext)I only receive a notification after the inserts and not after the deletes. If I restart the program, the database is empty, as expected. I never receive any notifications that have the Notification.deletedIdentifiers having any values in the array.
Question: Why don't I get a notification when I delete records?
NOTE: I know I can work-around this by calling self.reload() in the two remove()functions, but I was hoping the notification system would alert me as to when I need to reload. I prefer using the MVVM model where my ViewModel handles the fetches, inserts, deletes, etc. rather than using @Query macro in the actual View.
Also: using @Query in my code rather than a more MVVM style will show the changes on every save, so there must be a mechanism within SwiftData to notice when the underlying DB is modified.
