I am using SwiftData without using an app and it does not save automatically when it quits (.autosaveEnabled==true), so I thought I could call .mainContext.save() from the deinit of the swiftdata-owner, but it has to run on the MainActor and deinit does not allow async.
Is there a way to set up a Task on the MainActor that is somehow blocked until the deinit of the swiftdata-owner runs?
So basically instead of running the save-operation from the deinit I want to unblock a Task that does the saving on the MainActor. The unblocking should be done from the deinit of the swiftdata-owner.
All you have to do is get something out of self so that you don't capture self in the task. If you can say let container = self.container, and then access container.mainContext in the task, that works too.
Also, wasn't isolated deinit discussed at one point? Did that go anywhere?
deinit {
let thecontainer = container
Task { @MainActor [thecontainer] in
try! thecontainer.mainContext.save()
print("Did it…")
}
}
But it does not run the task... :-/ Seems like the Task in the deinit doesn't make it before the program quits? Or is there a bug in my code? (I am new to Swift concurrency).
Turns out that the Task does not run regardless of whether it appears in deinit or not, but it does run if it is placed before MainActor.run has been executed like this:
I had to add a dependency on the Task that was created in the deinit and wait on it at the end of the program.
Like this:
// global
public var pending:Task<(), Never>? = nil
…
deinit {
let thecontainer = container
pending = Task { @MainActor [thecontainer] in
…
}
}
…
// at the end of the main function of the program
_ = await pending?.result