Contents

WritableDocument

A document type that supports writing to file.

Declaration

protocol WritableDocument : AnyObject

Overview

Conform to WritableDocument to add save and export capabilities. Most documents also conform to ReadableDocument — use the Document protocol as a shorthand for both.

The document saving has three steps:

  1. SwiftUI calls snapshot(contentType:) on the main actor.

  2. SwiftUI calls writer(configuration:) to get a writer.

  3. The writer’s DocumentWriter/write(content:to:previous:progress:) runs in the background with coordinated file access.

Example using FileWrapperDocumentWriter:

@Observable
final class NoteDocument: WritableDocument {
    static let writableContentTypes: [UTType] = [.markdown]

    var text = ""

    func writer(configuration: sending WriteConfiguration) -> sending FileWrapperDocumentWriter<String> {
        FileWrapperDocumentWriter(configuration) { snapshot, _ in
            FileWrapper(
                regularFileWithContents: Data(snapshot.utf8)
            )
        }
    }

    @MainActor
    func snapshot(contentType: UTType) async throws -> sending String { text }
}

Register undo actions in the view using the environment’s UndoManager. This ensures SwiftUI detects unsaved changes and triggers autosave:

struct NoteEditorView: View {
    @Bindable var document: NoteDocument
    @Environment(\.undoManager) private var undoManager

    var body: some View {
        TextEditor(text: $document.text)
            .onChange(of: document.text) { oldValue, _ in
                undoManager?.registerUndo(
                    withTarget: document
                ) { document in
                    document.text = oldValue
                }
            }
    }
}

Topics

Writing a document

See Also

Storing document data in a reference type instance