I am seeing a strange warning pop up in my SwiftData ModelActor:
Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.
This warning is triggered by the try self.modelContext.save()
call in the following function in my ModelActor:
public func purgeLocalEvents(for calendarId: PersistentIdentifier) async {
do {
let calendars = try self.modelContext.fetch(CalendarFetchDescriptors.getCalendar(calendarId))
if let calendar = calendars.first {
if let events = calendar.events {
for event in events {
self.modelContext.delete(event)
}
}
calendar.lastSync = .distantPast
try self.modelContext.save()
}
} catch {
debugPrint("Error loading calendar for event purge", error.localizedDescription)
}
}
The function in the ModelActor is called like this:
Task.detached(priority: .userInitiated) {
let actor = await RemoteGoogleCalendarActor(modelContainer: SwiftDataCoordinator.shared.fullContainer)
await actor.purgeLocalEvents(for: calendarId)
}
I perform saves from modelactors in many other places, and I've never seen this warning before. What could be causing this issue?
The waring message says what it means: You probably updated a published property from a background queue.
modelContext.save
triggers notifications such as ModelContext.didSave or .NSManagedObjectContextDidSave from the queue where the save
method is called.
In your case, it seems that you use the model context provided by ModelActor
, and so the notifications will be triggered from a background queue. If you happen to observe the notifications and change a published property from within the notification handler, you will get the warning.
You can fix that kind of warning by running the code that updates the published property from the main queue (using MainActor
).
Best,
——
Ziqiao Chen
Worldwide Developer Relations.