Search code examples
swiftswiftuiobservedobjectdocument-based

Use of @StateObject in Document-based SwiftUI application: getting instances instead of references


I am trying to use a @Stateobject in my document as source of truth for the dataModel behind the document. However, it seems I am doing something wrong as I appear to get different instances for the document and the content view, which is in line with the warnings I am receiving: Accessing StateObject's object without being installed on a View. This will create a new instance each time.

Can anybody help? I am pretty sure this has a very simple fix...

Here is the code:

Observed Object:

class TestObject:ObservableObject{
    @Published var text: String
    init(){
        text = "initString"
    }
}

App:

@main
struct FileOpen5App: App {
    var body: some Scene {
        DocumentGroup(newDocument: FileOpen5Document()) { file in
            ContentView(document: file.$document, obj: file.document.docObject) /// instance warning
        }
    }
}

Document (partial):

struct FileOpen5Document: FileDocument {
    //var text: String
    @StateObject var docObject = TestObject()

    init() {
        docObject.text = "DocText" /// instance warning
    }
...

ContentView:

struct ContentView: View {
    @Binding var document: FileOpen5Document
    @ObservedObject var obj: TestObject
    
    var body: some View {
        Text(obj.text)
    }
}
'''


Solution

  • @StateObject is just for Views, try ReferenceFileDocument but before you resort to using classes I highly recommend figuring out if you can stick to structs because Swift and SwiftUI work best with value types. See https://developer.apple.com/documentation/swift/choosing_between_structures_and_classes