An Overview of the iOS 17 Document Browser View Controller

The previous chapters have introduced ways to integrate file handling into an iOS app in terms of local and cloud-based storage. In these chapters, the assumption has been made that all of the user interface aspects of the file handling and file system navigation will be provided in some way by the app itself. An alternative to integrating file handling in this way is to use the iOS document browser view controller. This chapter provides a basic overview of this class in preparation for a tutorial in the next chapter.

An Overview of the Document Browser View Controller

The document browser view controller is implemented using the UIDocumentBrowserViewController class and provides a visual environment in which users can navigate file systems and select and manage files from within an iOS app. In addition, the document browser provides the user with access to the local device file system, iCloud storage, and third-party providers such as Google Drive.

To see the browser in action, take some time to explore the Files app included as standard with iOS 17. Figure 43-1, for example, shows the iOS Files app browsing a user’s iCloud Drive files and folders:

Figure 43-1

When integrated into an app, the document browser provides the same functionality as the Files app in addition to the ability to create new files.

The Anatomy of a Document-Based App

The key elements that interact to provide the document browser functionality within an iOS app are a UIDocumentBrowserViewController instance, access to one or more file providers (for example, the local file system, iCloud Drive, Google Drive, etc.) and at least one additional view controller in which to present any selected file content to the user. When working with files in conjunction with the document browser, the use of the UIDocument class for the lower level file handling tasks is still recommended, so a subclass of UIDocument will also typically be included (the UIDocument class was covered in the chapter entitled Managing Files using the iOS 17 UIDocument Class).

 

You are reading a sample chapter from Building iOS 17 Apps using Xcode Storyboards.

Buy the full book now in eBook or Print format.

The full book contains 96 chapters and 760 pages of in-depth information.

Learn more.

Preview  Buy eBook  Buy Print

 

Adding document browser support to an app is a multistep process that begins with creating a UIDocumentBrowserViewController instance. When doing this, the browser must be the app’s root view controller. By far, the easiest way to start the development process is to use the Xcode iOS Document App template when creating a new project, as shown in Figure 43-2:

Figure 43-2

A project created using the Document Based App template will contain the following files by default:

  • DocumentBrowserViewController.swift – The root view controller for the app derived from the UIDocumentBrowserViewController class. This file contains stub delegate methods ready to be completed to implement app-specific document browser behavior.
  • Document.swift – A subclass of the UIDocument class containing stub methods.
  • DocumentViewController.swift – A template view controller intended to present the selected files to the user. This template implementation simply displays the file name and a “Done” button to return to the document browser.

Document Browser Project Settings

Some Info.plist settings must be configured to enable document browser support within an app project. The first is the Supports Document Browser (UISupportsDocumentBrowser) key, which must be set to YES.

Next, the app must declare the document types it can handle and the action it can perform on those types (i.e., viewing only or viewing and editing). These settings dictate the types of files that will be selectable within the document browser.

Each supported type must, at a minimum, include the following key-value information:

 

You are reading a sample chapter from Building iOS 17 Apps using Xcode Storyboards.

Buy the full book now in eBook or Print format.

The full book contains 96 chapters and 760 pages of in-depth information.

Learn more.

Preview  Buy eBook  Buy Print

 

  • CFBundleTypeName – A string value that uniquely identifies the type within the app’s context.
  • CFBundleTypeRole – A string value indicating the action that the app will perform on the file (i.e., Editor or Viewer)
  • LSHandlerRank – A string value that declares to the system how the app relates to the file type. If the app uses its own custom file type, this should be set to Owner. If the app is to be opened as the default app for files of this type, the value should be set to Default. If, on the other hand, the app can handle files of this type but is not intended to be the default handler, a value of Alternate should be used. Finally, None should be used if the app is not to be associated with the file type.
  • LSItemContentTypes – An array of Universal Type Identifiers (UTI) indicating the file types supported by the app. These can be custom file types unique to the app or, more commonly, standard identifiers provided by Apple, such as public.image, public.text, public.plain-text, and public.rtf.

As outlined in the next chapter, the easiest way to configure these keys is within the Info panel of the Xcode project target screen.

The Document Browser Delegate Methods

When the user selects a file from within the document browser of an app, several delegate methods implemented within the document browser view controller will be called. These methods can be summarized as follows:

didRequestDocumentCreationWithHandler

This method is called when the user requests to create a new file within the document browser. This method is responsible for providing a template file and passing the URL for that file to the importHandler method. The template file can either be a file that is already bundled with the app or a file that is created on demand within the delegate method. This method also allows the app to display a selection screen to choose the template type if the app supports more than one file type or template option.

The importHandler method interacts with the appropriate file provider to create the file in the designated location. If, for example, the user was browsing an iCloud Drive location when making the file creation request, the importHandler method will work with the iCloud Drive file provider to create the new file in that location.

In addition to providing the URL of the template file, the importHandler method also needs to be passed a value indicating whether the template file should be moved (.move) or copied (.copy) to the location on the file provider. A move operation is more likely if the delegate method creates a temporary file to act as the template. However, for a template file bundled with the app, it will make more sense to copy the file since it will need to be available for future creation operations.

 

You are reading a sample chapter from Building iOS 17 Apps using Xcode Storyboards.

Buy the full book now in eBook or Print format.

The full book contains 96 chapters and 760 pages of in-depth information.

Learn more.

Preview  Buy eBook  Buy Print

 

If the user cancels the creation process, the importHandler method must be called with a nil file URL and a none (.none) value. The following code shows an example method implementation that uses a bundled file named template.txt as the template:

func documentBrowser(_ controller: UIDocumentBrowserViewController, 
  didRequestDocumentCreationWithHandler importHandler: @escaping (URL?, 
   UIDocumentBrowserViewController.ImportMode) -> Void) {
    
    let newDocumentURL: URL? = Bundle.main.url(forResource: "template", 
					withExtension: "txt")
    
    if newDocumentURL != nil {
        importHandler(newDocumentURL, .copy)
    } else {
        importHandler(nil, .none)
    }
}Code language: Swift (swift)

didImportDocumentAt

This method is called when a new document has been successfully created by the file provider (in other words, the importHandler method call was successful). When called, this method is passed both the local template file’s source URL and the file’s destination URL, now residing on the file provider. In addition, this method will typically display the view controller that is responsible for presenting the file content to the user:

func documentBrowser(_ controller: UIDocumentBrowserViewController, 
  didImportDocumentAt sourceURL: URL, toDestinationURL destinationURL: URL) {
        
    presentDocument(at: destinationURL)
}Code language: Swift (swift)

The presentDocument method called in the above example is a helpful utility method included as part of the Document Based App project template for the document browser view controller class.

didPickDocumentURLs

This method is called when the user requests to open one or more existing files within the document browser. The URLs for the selected files are passed to the method in the form of an array, and it is the responsibility of this method to pass these URLs to and present the document view controller. The default implementation for this method passes the first URL in the array to the presentDocument method:

func documentBrowser(_ controller: UIDocumentBrowserViewController, 
  didPickDocumentURLs documentURLs: [URL]) {
        guard let sourceURL = documentURLs.first else { return }
        
    presentDocument(at: sourceURL)
}Code language: Swift (swift)

failedToImportDocumentAt

Called when the document import request fails, this method should notify the user of the failure, details of which can be extracted from the error object:

 

You are reading a sample chapter from Building iOS 17 Apps using Xcode Storyboards.

Buy the full book now in eBook or Print format.

The full book contains 96 chapters and 760 pages of in-depth information.

Learn more.

Preview  Buy eBook  Buy Print

 

func documentBrowser(_ controller: UIDocumentBrowserViewController, 
  failedToImportDocumentAt documentURL: URL, error: Error?) {

        notifyUser(error?.localizedDescription
}Code language: Swift (swift)

Customizing the Document Browser

Several properties are available for customizing the document browser. The allowsPickingMultipleItems property controls whether the user can select multiple files:

allowsPickingMultipleItems = falseCode language: Swift (swift)

The allowsDocumentCreation property defines whether the user can create new files (essentially defining whether or not the create file buttons appear in the browser):

allowsDocumentCreation = trueCode language: Swift (swift)

The visual appearance of the browser can be changed by setting the browserUserInterfaceStyle property to dark, light, or white:

browserUserInterfaceStyle = .darkCode language: Swift (swift)

Finally, the tint color used by the browser (primarily the color used for text foreground and icons) can be changed via the tintColor property:

view.tintColor = .yellowCode language: Swift (swift)

Adding Browser Actions

Performing a long press on a file within the document browser displays the edit menu (Figure 43-3) containing a range of built-in options, including copy, delete, rename, and share.

 

You are reading a sample chapter from Building iOS 17 Apps using Xcode Storyboards.

Buy the full book now in eBook or Print format.

The full book contains 96 chapters and 760 pages of in-depth information.

Learn more.

Preview  Buy eBook  Buy Print

 

Figure 43-3

These options also appear in the navigation bar at the bottom of the screen when the user enters select mode by tapping the Select button in the top right-hand corner of the browser window.

Custom actions may be added to these menus by assigning an array of UIDocumentBrowserActions objects to the customActions property of the document browser view controller instance. A UIDocumentBrowserActions object consists of a unique identifier, a string to appear on the button, an array of locations where the action is to be available (options are menu and navigation bar), and a completion handler to be called when the action is selected. In addition, the completion handler is provided with an array of URLs representing the files selected when the action was triggered.

The action object also needs to be configured with the file types for which it is to appear and a property setting indicating whether the action can work with multiple file selections. The following example creates and assigns a browser action for text and plain text file types that works only with single file selections and displays “Convert” as the action title:

let action = UIDocumentBrowserAction(identifier: 
   "com.ebookfrenzy.docdemo.convert", localizedTitle: "Convert",
        availability: [.menu, .navigationBar], handler: { urls in

	// Code to be executed when action is selected                                                

})

action.supportedContentTypes = ["public.text", "public.plain-text"]
action.supportsMultipleItems = false
customActions = [action]Code language: Swift (swift)

Summary

The UIDocumentBrowserViewController class provides an easy way to build document browsing into iOS apps. The document browser can be integrated with minimal programming effort and is designed to integrate with the local filesystem, iCloud Drive, and other third-party file providers such as Google Drive and DropBox. Integration primarily consists of adding a UIDocumentBrowserViewController as the root view controller, setting some Info.plist properties, and writing some delegate methods. Much preparatory work is performed automatically when a new Xcode project is created using the Document Based App template.


Categories