I have made an app based on the new SwiftUI multi platform target for a "Document based app". However, I face weird issues. As long as an app is in the foreground, it works just fine. If it is moved to the background by task switching, and then again to the foreground, mutations are being saved to the document, but the SwiftUI Views don't receive mutations. So whenever you press a button in the UI that mutates the document you see nothing happening while the mutation is there once you reload the document from disk.
So i am thinking, I use ObservedObjects, they probably get kicked out of memory once I move to the background. could this be the cause of my bug?
But then I added a print line to the App struct.
import SwiftUI
@main
struct MyApp: App {
fileprivate func myLogging(_ file: FileDocumentConfiguration<MyDocument>) -> some View {
print("""
IT IS CALLED
""")
return MainView().environmentObject(BindingWrapper(file.$document))
}
var body: some Scene {
DocumentGroup(newDocument: MyDocument()) { (file) in
return myLogging(file)
}.commands { AppCommands() }
}
}
and guess what... this print always executes just before a mutation is being rendered. Which makes sense. because file.$document
is a binding, and if you do a mutating action, the binding will warn Apple that the file is dirty, but it will also invalidate the entire hierarchy. This logging will still print once the bug has occurred!
So on the line MainView().environmentObject(BindingWrapper(file.$document))
I assume everything is created from scratch. BindingWrapper is a custom class I made to convert a binding in an observable object. And this is one of the objects I worried about, that they might be freed. but if they are created newly.... they should be always there, right?
And by the way, this object is owned by the environment. So it should not be freed.
So, now I am stuck. is Apple doing some clever caching on bindings / ObservedObjects which will inject old objects into my view hierarchy even though I think everything is created newly?