Building an app with a document browser
Provide access to on-device and cloud files by adding a document browser to your app.
Overview
The Document Browser sample code uses a UIDocumentBrowserViewController as the app’s root view controller. The browser defines the structure of the app, and the app displays the browser view when it launches. A person can then use the browser to:
Browse all the text files on the person’s device, in their iCloud drive, or in any supported third-party file providers.
Create new text files.
Open text files.
When someone opens a file, the app transitions to an editor view. There, the person can edit and save the text file. When they are done editing, the app returns to the browser, letting the person open or create another file.
This sample code project demonstrates all the required steps to set up the document browser, to work with the person’s files, and to enable system animations. The following sections describe these steps in more detail.
Setting up the document browser
The Document Browser app performs the following setup and configuration steps:
Assigns a UIDocumentBrowserViewController subclass as the window’s rootViewController.
Specifies the supported document types.
Customizes the document browser’s behavior.
Apps based on a document browser assign a UIDocumentBrowserViewController instance as the app’s rootViewController, ensuring that the browser remains in memory throughout the app’s lifetime.
The sample code defines a UIDocumentBrowserViewController subclass named DocumentBrowserViewController. It then marks the subclass as the app’s initial view controller in the Main.storyboard storyboard, and displays the browser view when launched.
Apps based on a document browser also declare the document types that they can open. The sample code app declares support for text files in the project editor’s Info pane. For more information on setting the document type, see Setting up a document browser app.
Finally, the sample code configures the document browser in the DocumentBrowserViewController class’s viewDidLoad() method. Specifically, it enables document creation, and disables multiple document selection. This lets users create new documents from the browser, while also preventing them from opening more than one document at a time.
allowsDocumentCreation = true
allowsPickingMultipleItems = falseFor more information on configuring a document browser, see Customizing the document browser.
Creating new documents
When the user creates a new document, the system calls the document browser delegate’s documentBrowser(_:didRequestDocumentCreationWithHandler:) method.
// Create a new document.
func documentBrowser(_ controller: UIDocumentBrowserViewController,
didRequestDocumentCreationWithHandler importHandler: @escaping (URL?, UIDocumentBrowserViewController.ImportMode) -> Void) {
os_log("==> Creating A New Document.", log: .default, type: .debug)
let doc = TextDocument()
let url = doc.fileURL
// Create a new document in a temporary location.
doc.save(to: url, for: .forCreating) { (saveSuccess) in
// Make sure the document saved successfully.
guard saveSuccess else {
os_log("*** Unable to create a new document. ***", log: .default, type: .error)
// Cancel document creation.
importHandler(nil, .none)
return
}
// Close the document.
doc.close(completionHandler: { (closeSuccess) in
// Make sure the document closed successfully.
guard closeSuccess else {
os_log("*** Unable to create a new document. ***", log: .default, type: .error)
// Cancel document creation.
importHandler(nil, .none)
return
}
// Pass the document's temporary URL to the import handler.
importHandler(url, .move)
})
}
}In this method, the app creates, saves, and then closes a new text document. If successful, the app passes the URL to the method’s import handler, requesting that the system move the document to its final location. Otherwise, it passes nil to the import handler, canceling document creation.
Opening and importing documents.
People can open documents in multiple ways. The sample code handles the following situations:
If the app imports a document (including successfully creating a new document), the system calls the documentBrowser(_:didImportDocumentAt:toDestinationURL:) method.
If someone selects a document from the browser, the system calls the documentBrowser(_:didPickDocumentURLs:) method.
If someone shares a document with the app, or drags a document into the app, the system calls the app delegate’s application(_:open:options:) method.
In the first two cases, the app calls the custom presentDocuments(at:) method. In the third case, the app calls the browser’s revealDocument(at:importIfNeeded:completion:) method to import the document, if needed. It then calls the presentDocuments(at:) method.
The presentDocuments(at:) method instantiates a TextDocumentViewController, sets up the document’s animation, opens the document, and then presents the view controller by calling the browser’s present(_:animated:completion:) method.
Enabling animations
The document browser provides two built-in animations: one for loading a file, another for transitioning to and from the document view.
To enable either of the system-provided document browser animations, first you need to request a transition controller for the document by calling the transitionController(forDocumentURL:) method.
transitionController = transitionController(forDocumentAt: documentURL)To enable the loading animation, assign a Progress object to the transition controller when you begin to load the document.
// Set up the loading animation.
transitionController!.loadingProgress = doc.loadProgressIncrement the progress as the document loads, making sure to mark it as complete as soon as loading finishes. To simulate slow, incremental loading in the sample code project, uncomment the TextDocument class’s read(from:) method.