Skip to content

File Importing and Exporting (SwiftUI)

A SwiftUI guide for coding agents. Also covers fileimporter, fileexporter, filedocument protocol, open file dialog ios, save file swiftui, filemover.

Three view modifiers cover file management: fileImporter picks a file, fileExporter saves a FileDocument, and fileMover relocates an existing file. Each one presents the system dialog from a boolean binding.

Import

fileImporter handles the dialog and folder navigation. Restrict what the user can pick with allowedContentTypes, and read the chosen URL in the completion closure.

Button("Import") { importing = true }
    .fileImporter(
        isPresented: $importing,
        allowedContentTypes: [.plainText]
    ) { result in
        switch result {
        case .success(let file): print(file.absoluteString)
        case .failure(let error): print(error.localizedDescription)
        }
    }

Export

Exporting needs a document type conforming to FileDocument: declare its content types, read from a ReadConfiguration, and write through a FileWrapper.

struct TextDocument: FileDocument {
    static var readableContentTypes: [UTType] { [.plainText] }

    var text = ""

    init(text: String) { self.text = text }

    init(configuration: ReadConfiguration) throws {
        if let data = configuration.file.regularFileContents {
            text = String(decoding: data, as: UTF8.self)
        } else {
            text = ""
        }
    }

    func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
        FileWrapper(regularFileWithContents: Data(text.utf8))
    }
}

fileExporter then takes the document and its content type, plus the presentation binding.

Button("Export") { exporting = true }
    .fileExporter(
        isPresented: $exporting,
        document: document,
        contentType: .plainText
    ) { result in
        // .success(URL) or .failure(Error)
    }

Moving

fileMover presents the move dialog for a file URL you already hold and reports the new location in its completion closure.

Button("Move files") { moving = true }
    .fileMover(isPresented: $moving, file: file) { result in
        // .success(URL) or .failure(Error)
    }

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-swiftui-guide({ topic: "swiftui-file-importing-and-exporting" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems