Build document-based apps in SwiftUI
For document based apps, use the DocumentGroup
scene as the main scene of the app:
DocumentGroup(newDocument: MyDocument()) { file in ContentView(document: file.$document) }
The content view receives a binding to the document contents, so when it changes the contents, the system knows it was modified
Document based apps have a “Document Types” section in the Info.plist
, where you declare Uniform Type Identifiers of document types associated with your app
Imported types ⭢ documents from other apps or sources that your app is able to open
Exported types ⭢ document types owned by your app
TextEditor()
– built in text view type
The type that implements the document model conforms to FileDocument
(for value types) and declares its own UTType
instances that represent imported and exported file types:
import UniformTypeIdentifiers extension UTType { static var exampleText: UTType { UTType(importedAs: "com.example.plain-text") } static let shapeEditDocument = UTType(exportedAs: "com.example.ShapeEdit.shapes") }
Imported type needs to be a computed property, because the value returned from the constructor may change between calls while the app is running, depending on system configuration. Exported type can just be assigned once and stored.
The document type provides a list of types (own and generic) that it can accept:
static var readableContentTypes: [UTType] { [.exampleText] }
It also has methods for reading and writing its document to/from a file, which you need to implement, using e.g. Codable to encode/decode the value into your chosen format:
init(fileWrapper: FileWrapper, contentType: UTType) throws { ... } func write(to fileWrapper: inout FileWrapper, contentType: UTType) throws { ... }
In those methods, you can assume that the content type is one of those you declared as accepted by your app.