Build document-based apps in SwiftUI
Show Apple's description.
Learn how to build a document-based app entirely in SwiftUI! We’ll walk you through the DocumentGroup API and how it composes with your App and Scenes, allowing you to add out-of-the-box support for document management — such as document browsing and standard commands — no heavy lifting required. You’ll learn to set up Universal Type Identifiers as well as gain understanding into what makes a top-notch document-based app. To get the most out of this session, you should first familiarize yourself with building apps in SwiftUI. Check out "App essentials in SwiftUI" to learn more.
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.
This note was originally published at https://mackuba.eu/notes/wwdc20/build-document-based-apps-in-swiftui/