<!--
{
  "availability" : [
    "iOS: 27.0.0 -",
    "iPadOS: 27.0.0 -",
    "macCatalyst: 27.0.0 -",
    "macOS: 27.0.0 -",
    "visionOS: 27.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "SwiftUI",
  "identifier" : "/documentation/SwiftUI/WritableDocument",
  "metadataVersion" : "0.1.0",
  "role" : "Protocol",
  "symbol" : {
    "kind" : "Protocol",
    "modules" : [
      "SwiftUI"
    ],
    "preciseIdentifier" : "s:7SwiftUI16WritableDocumentP"
  },
  "title" : "WritableDocument"
}
-->

# WritableDocument

A document type that supports writing to file.

```
protocol WritableDocument : AnyObject
```

## Overview

Conform to `WritableDocument` to add save and export
capabilities. Most documents also conform to
[`ReadableDocument`](/documentation/SwiftUI/ReadableDocument) — use the [`Document`](/documentation/SwiftUI/Document) protocol as a
shorthand for both.

The document saving has three steps:

1. SwiftUI calls [`snapshot(contentType:)`](/documentation/SwiftUI/WritableDocument/snapshot(contentType:)) on the main actor.
2. SwiftUI calls [`writer(configuration:)`](/documentation/SwiftUI/WritableDocument/writer(configuration:)) to get a writer.
3. The writer’s
   `DocumentWriter/write(content:to:previous:progress:)` runs
   in the background with coordinated file access.

> Important: Without registered undo actions, SwiftUI won’t
> trigger autosave. Register undo actions with the undo manager
> from the `View` environment for every user-facing change.

Example using [`FileWrapperDocumentWriter`](/documentation/SwiftUI/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

[`writableContentTypes`](/documentation/SwiftUI/WritableDocument/writableContentTypes)

The content types this document can save or export to.

[`WriteConfiguration`](/documentation/SwiftUI/WritableDocument/WriteConfiguration)

The configuration for writing document contents.

[`Writer`](/documentation/SwiftUI/WritableDocument/Writer)

A type that implements writing to disk.

[`writer(configuration:)`](/documentation/SwiftUI/WritableDocument/writer(configuration:))

Creates a writer to save this document to disk.

[`snapshot(contentType:)`](/documentation/SwiftUI/WritableDocument/snapshot(contentType:))

Captures the document’s current state for saving.

## Relationships

### Inherited By

[`Document`](/documentation/SwiftUI/Document)

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)