Using ReferenceFileDocument in SwiftUI
Create a SwiftUI document-based app using reference types instead of value types for your document
At WWDC 2020, Apple introduced the creation of document-based apps created entirely in SwiftUI using the new DocumentGroup
element. Along with this new addition, Xcode 12 also provides a built-in template for generating a document-based app using SwiftUI using FileDocument
. The new template works great out-of-the-box if you are using value types for your document, but what about using reference types?
Luckily, Apple thought of this and also provided us with a protocol for reference typed documents called ReferenceFileDocument
but (as of the time of writing this article) have not yet explained its usage. In this article, I will demonstrate how to use ReferenceFileDocument
by converting Apple’s provided Xcode template to use reference types.
To start, create a new Xcode project using the Multiplatform -> Document App
template type. Open the generated <YourProjectName>Document.swift
file and have a look around. As you can see, Xcode has generated a struct for our document that adopts the FileDocument
protocol. The first thing we need to do is to change this struct to a class and change the protocol to useReferenceFileDocument
:
If you build and run now you will get an error, but we will soon be fixing that problem. To solve the complier issues, next we need to properly conform to the ReferenceFileDocument
protocol.
Next, replace the existing write()
function with the following:
As you can see the ReferenceFileDocument
protocol replaces the write()
function with a new version that passes a Snapshot
to the function that is provided by our implementation of the snapshot()
method. Apple documentation describes Snapshot
as:
A type of the document snapshot that can be used for serialization in parallel to the main document being editable.
In simpler terms this is just a “copy” of our current document state that will be written to the file on save. In this example we are simply returning the current value of self.text
.
Now there is just one more piece of housekeeping in our document file to update. ReferenceFileDocument
conforms to the ObservableObject
protocol so in order for our document changes to be observable to SwiftUI we need to add @Published
property wrapper to our text
variable:
There is just a couple more steps required before we can build and run our project. Navigate over to <YourProjectName>App.swift
and replace the body
property with the following:
Lastly, we need to change the document
variable in ContentView.swift
to use @ObservedObject
instead of @Binding
:
With that last change we are done! Build and run the project and try out your shiny new document-based app using reference types!
Happy coding!
Resources
- Download full source code for this tutorial here.