TechnologiesSwiftUIDocuments

FileWrapperDocumentReader struct

iOSmacOStvOSwatchOSvisionOS✓ renders

A document reader that uses `FileWrapper` for reading.

How it works

FileWrapperDocumentReader is the structure SwiftUI hands to a document type when it needs to materialize that document's contents from a file wrapper on disk. It bridges the bytes of a saved file — whether a single regular file or a directory of related resources — to the typed model your app actually works with, so your document never has to manage file handles or paths directly. Reach for it as the read side of the document lifecycle, the counterpart to writing a FileWrapper back out, when you adopt the document-based app model and conform a type to FileDocument.

  1. Declare the type you read into with FileDocument

    The reader populates a value type that conforms to FileDocument. In the example, NoteDoc is that type: it owns the in-memory model (var text: String) that the reader will fill from disk, keeping document storage separate from any view.

  2. Advertise what you can read with readableContentTypes

    A document declares the formats it understands so the system only offers it files it can actually open. NoteDoc returns [.plainText] from readableContentTypes, telling the reader to route plain-text file wrappers to this type.

  3. Decode in init(configuration:) from the file wrapper

    The read entry point is init(configuration: ReadConfiguration). The configuration exposes the resolved file wrapper, and you reach its bytes through configuration.file.regularFileContents; here those Data bytes are turned into a String to set text, the moment the wrapper's contents become your model.

  4. Fail loudly on unreadable contents

    Because reading can encounter missing or malformed data, the initializer is throws. When regularFileContents is nil or the bytes aren't valid UTF-8, NoteDoc throws CocoaError(.fileReadCorruptFile), signaling the reader that this file can't be opened rather than producing a half-formed document.

  5. Round-trip with fileWrapper(configuration:)

    The reader's symmetry is the write path: fileWrapper(configuration: WriteConfiguration) returns a new FileWrapper(regularFileWithContents:) built from the same text, so what the reader decodes and what the document serializes describe one format end to end.

Try it — Change String(data: data, encoding: .utf8) to encoding: .ascii and open a file containing non-ASCII characters: the decode returns nil, the initializer throws CocoaError(.fileReadCorruptFile), and you see the reader reject the document instead of loading it.

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

FileWrapperDocumentReader.swift
struct FileWrapperDocumentReaderDemo: View {
    struct NoteDoc: FileDocument {
        static var readableContentTypes: [UTType] { [.plainText] }
        var text: String
        init(text: String = "") { self.text = text }
        init(configuration: ReadConfiguration) throws {
            guard let data = configuration.file.regularFileContents,
                  let str = String(data: data, encoding: .utf8)
            else { throw CocoaError(.fileReadCorruptFile) }
            text = str
        }
        func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
            FileWrapper(regularFileWithContents: Data(text.utf8))
        }
    }

    @State private var doc = NoteDoc(text: "Hello from a file wrapper.")

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            Label("Note.txt", systemImage: "doc.text")
                .font(.headline)
            Text(doc.text)
                .foregroundStyle(.secondary)
        }
        .padding()
    }
}
Live preview
Note.txt Hello from a file wrapper.
Note.txt Hello from a file wrapper.
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →