How it works
DocumentReadConfiguration is the value SwiftUI hands to a FileDocument when the system opens an existing file on disk. It packages everything your type needs to reconstruct itself: the file's contents as a FileWrapper and the content type that was matched. You reach for it inside the throwing init(configuration:) initializer, where it serves as the single source of truth for the bytes you are about to decode. It is typically referred to through the FileDocument.ReadConfiguration type alias rather than spelled out in full.
Receive the configuration in init(configuration:)
FileDocument's required throwing initializer takes one DocumentReadConfiguration parameter, surfaced here as
init(configuration: ReadConfiguration). SwiftUI calls this when a document is opened, passing a fully-populated configuration so your type can rebuild its in-memory state from persisted data.Reach the bytes through file.regularFileContents
The configuration's
fileproperty is a FileWrapper describing what was loaded; for a flat file you pull the raw bytes fromconfiguration.file.regularFileContents, which is optional because the wrapper might represent a directory instead. The example unwraps it with aguard let databefore decodingString(data: data, encoding: .utf8).Fail loudly with a thrown error
Because init(configuration:) is throwing, a configuration whose contents can't be decoded should not produce a half-formed document. When the bytes are missing or invalid UTF-8, the example throws
CocoaError(.fileReadCorruptFile), letting SwiftUI surface a proper open failure to the user.Constrain what arrives via readableContentTypes
The content delivered in the configuration is gated by the type's
readableContentTypes, here[.plainText]. Only files matching those UTTypes are routed into init(configuration:), so the data you read from the configuration is already narrowed to formats you declared you can handle.Round-trip with the write side
DocumentReadConfiguration is the read counterpart to WriteConfiguration: what
fileWrapper(configuration:)serializes withFileWrapper(regularFileWithContents:)is exactly what a later read sees throughconfiguration.file.regularFileContents. Keeping the two symmetric is what makes save-then-open preserve the document faithfully.
String(data: data, encoding: .utf8) with String(data: data, encoding: .ascii) and open a file containing non-ASCII characters to watch the guard fail and the configuration's contents trigger the thrown CocoaError(.fileReadCorruptFile).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.
struct DocumentReadConfigurationDemo: View {
// DocumentReadConfiguration is handed to FileDocument.init(configuration:)
// during a document open. It exposes the file's contentType and raw data.
struct Note: 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 string = String(data: data, encoding: .utf8) else {
throw CocoaError(.fileReadCorruptFile)
}
text = string
}
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
FileWrapper(regularFileWithContents: Data(text.utf8))
}
}
@State private var doc = Note(text: "Hello, document!")
var body: some View {
VStack(alignment: .leading, spacing: 8) {
Text("FileDocument")
.font(.headline)
Text(doc.text)
.font(.body)
.foregroundStyle(.secondary)
Text("Read via init(configuration:)")
.font(.caption)
.foregroundStyle(.tertiary)
}
.padding()
}
}