Using ReferenceFileDocument to Save SwiftUI Documents

When you create a SwiftUI Document App project, the Swift file for the document contains a struct for the document that conforms to FileDocument. Using a struct for the document works in most cases, but you can make the document a class by conforming to ReferenceFileDocument.

When to Make Your SwiftUI Document a Class

The most common reason to use a class for a SwiftUI document is to update SwiftUI views when a property in the document changes. Using the @Published property wrapper for a property triggers updates to SwiftUI views when the property’s value changes. But the @Published property wrapper works only for classes.

If you are going to pass the document to many views, it can be more effective to make the document a class and use @StateObject, @ObservedObject, or @EnvironmentObject to pass the document to other views.

If you can’t mark the document as changed when using a struct, you can mark the document as changed by making the document a class and registering with the undo manager.

Changing the Document from a Struct to a Class

Apple’s Swift file for the document creates a struct.

You must make the following changes to change the document from a struct to a class:

  • Change struct to class
  • Change FileDocument to ReferenceFileDocument
  • Have the document conform to ObservableObject

Creating a Snapshot

You must add a snapshot function to your document’s class to use ReferenceFileDocument. The snapshot function creates a snapshot of the document’s current state that SwiftUI uses to save the document.

Replace GameScene with the data type your document saves. Replace scene with a property in your document class.

Marking the Document as Changed

If you find your document isn’t marked as changed when you make changes to the document, register your document with the undo manager by calling the registerUndo function. Usually you call registerUndo from a view’s .onAppear modifier.

Acknowledgements

The answers to the following questions on Stack Overflow helped me write this article: