fileExporter(isPresented:document:contentType:defaultFilename:onCompletion:onCancellation:)
Presents a system dialog for allowing the user to export a WritableDocument to a file on disk.
Declaration
nonisolated func fileExporter<D>(isPresented: Binding<Bool>, document: D?, contentType: UTType? = nil, defaultFilename: String? = nil, onCompletion: @escaping (Result<URL, any Error>) -> Void, onCancellation: (() -> Void)? = nil) -> some View where D : WritableDocument, D.Writer.Destination == URL
Parameters
- isPresented:
A binding to whether the dialog should be shown.
- document:
The in-memory document to export.
- contentType:
The content type to export to. If not provided,
WritableDocument.writableContentTypesare used. - defaultFilename:
If provided, the default name to use for the exported file, which the user will have an opportunity to edit prior to the export.
- onCompletion:
A callback that will be invoked when the operation has succeeded or failed. The
resultindicates whether the operation succeeded or failed. - onCancellation:
A callback that will be invoked if the user cancels the operation.
Discussion
In order for the dialog to appear, document must be non-nil. When the operation is finished, isPresented will be set to false before onCompletion is called. If the user cancels the operation, isPresented will be set to false and onCancellation will be called.
Below is an example of a simple implementation of WritableDocument. Instead of String, you can use Data or any other type as the snapshot.
@MainActor
final class TextDocument: WritableDocument {
static let writableContentTypes: [UTType] = [.utf8PlainText]
var text: String = ""
nonisolated func writer(
configuration: sending WriteConfiguration
) -> sending FileWrapperDocumentWriter<String> {
FileWrapperDocumentWriter(configuration) { snapshot, _ in
FileWrapper(regularFileWithContents: Data(snapshot.utf8))
}
}
func snapshot(contentType: UTType) async throws -> String {
text
}
}
struct ExportView: View {
@State private var document = TextDocument()
@State private var isExporting = false
var body: some View {
Button("Export…") { isExporting = true }
.fileExporter(
isPresented: $isExporting,
document: document,
defaultFilename: "Untitled"
) { _ in }
}
}See Also
Exporting to file
fileExporter(isPresented:document:contentType:defaultFilename:onCompletion:)fileExporter(isPresented:documents:contentType:onCompletion:)fileExporter(isPresented:document:contentTypes:defaultFilename:onCompletion:onCancellation:)fileExporter(isPresented:documents:contentTypes:onCompletion:onCancellation:)fileExporter(isPresented:item:contentTypes:defaultFilename:onCompletion:onCancellation:)fileExporter(isPresented:items:contentTypes:onCompletion:onCancellation:)fileExporterFilenameLabel(_:)