Skip to main content

How to Integrate Your App with Files App in iOS 11

In this tutorial, I’ll show you how to embrace iOS 11’s Files app. First, I’ll walk you through configuration of an app so that any files stored in its iOS file system-based “Documents” folder are made visible in the Files app and exposed to other apps installed on your device. Second, I’ll demonstrate how you can incorporate Files app-like interface and functionality into your own apps. All of the Swift code I wrote to accomplish these two tasks is included below — and I’ve taken lots of screenshots regarding Files app integration. Sit back, enjoy, and learn about a fundamental paradigm shift in the iOS zeitgeist, moving from a “hide-the-details” (like hiding individual files) mindset to providing users with the ability to look at and manipulate files related to their apps using a macOS Finder-like interface, except on iOS.
To pique your interest, let’s look at a feature I encoded in the final app for this tutorial. We’ll use my app, named “Document-Based App,” to view an image file in the app’s main folder:

Introduction

Most iOS app developers — and users — are not accustomed to seeing the files associated with their apps, at least not in a Finder-like or Explorer-like or even command line-like listing format. In other words, they’re not used to seeing files organized as just files and directories and being able to navigate around in a file system. For years, the closest thing to an iOS file browser has been through apps like Photos, where you can see individual thumbnail images of photos hinting at the fact that their content is stored in individual files. But Photos gives you no sense of how the image files are organized… In folders or subfolders? Which folders and where in your device’s file system?
iOS 11 changed all that with the introduction of the Files app.
Note that before the Files app, developers like myself had to build custom Finder-like hierarchical file/directory user interface (UI) representations of the iOS file system, and provide corresponding functionality for navigation and manipulation of files and folders. Download one of my iPad-based apps to see an example of my custom file “explorer” or “finder” here — it’s a free app.

Exposing Your App’s File to the Files App

Let’s first walk through the basic use of the Files app. Remember that you must be running iOS 11 to follow along with this tutorial. I’ve found that many people out there, even amongst developers, haven’t even used the Files app yet. Let’s look at how the app works, and remember that today I’m limiting my discussion only to files stored locally on a device — an iPhone in this case. Getting into iCloud or Dropbox support is too much for one tutorial. I’ll start up the Files app and show you how to view files stored locally on your device:
For the purposes of this tutorial, we’ll always want to “Browse” to the “location” called “On My iPhone,” as you just saw in the previous graphic.
Whether you actively use it or not, every iOS app you develop has its own unique sandboxed file system comprised of a set of directories, most notably the “Documents” directory. Detailed discussion of the iOS file system’s structure and how you perform tasks like reading, writing, deleting, renaming, moving, and listing files is beyond the scope of this tutorial, but don’t worry if this is all new to you. I’ve wrote several detailed tutorials covering most salient iOS file management topics, for example, here and here.
Developers who want to expose certain app files to users should always use the “Documents” directory. Files meant for internal use, like templates or configuration files, or temporary files say, used for converting files between different formats, should be stored in other predefined sandboxed folders like “Library/” or “tmp/”.

Opting your app into showing its files in the Files app

Caution: By exposing your app’s files to the Files app, you’re also making those same files available to other developers’ apps. Think about it carefully before you write things like a user’s personal information or details about your own proprietary trade secrets into files that will be made possibly public.
Configuring your app so that its files appear in the Files app is pretty simple. I’ll show you how by setting up the app I used in a tutorial for explaining the iOS file system, named “iOS File Management.” It’s a great candidate for opting into the Files app because it contains Swift code for reading, writing, deleting, renaming, moving, and listing iOS files.
The easiest way to configure the app is to add the following two keys inside the main <dict> in the Xcode project’s Info.plist file:
Remember that you can view and edit an Xcode project’s Info.plist file as XML by:
  • going to the Project Navigator;
  • right-clicking or control-clicking on the Info.plist file; and,
  • selecting Open As -> Source Code from the context menu.
If you prefer to edit the Info.plist file through Xcode’s default property list interface, hover your mouse over an existing entry and press the plus sign (+) that appears. Add the two keys I showed above and set each of their Value toggles to “YES,” like so:
There are good definitions of both of these keys at this link. You can see my project’s Info.plist file with these two keys added here and the whole project here in my GitHub repo.
I’ll now install the newly-configured “iOS File Management” app on my iPhone. I added some code in the viewDidLoad method of my only UIViewControllersubclass. That code runs on app startup and writes a text file named “textFile1.txt” into the app’s “Documents” folder.
Let’s look for that file in the Files app:
See the folder representing my “iOS File Management” app’s files? It contains the file, “textFile1.txt,” that I encoded to be written on startup of the app. You can even see a thumbnail via (Quick Look) previewing the contents of my text file. Here’s some iOS documentation from Apple that describes the keys I added to my “iOS File Management” app’s Info.plist file, providing the perfect segue (segue?) — into the rest of this tutorial:
To give other apps access to the files in your Documents directory, just set the proper keys in your app’s Info.plist file. You can either set the UISupportsDocumentBrowser key (for document browser-based apps), or set both the UIFileSharingEnabled and LSSupportsOpeningDocumentsInPlace keys.
These keys enable other apps to open and edit the contents of your Documents directory in place. Your files also appear in both the Files app and the document browser. For more information, see the UIDocumentBrowserViewController class.

Providing a File App-like Experience

Let’s pick up right where we left off in the last section of this tutorial where I mentioned building “document browser-based apps” using a UIDocumentBrowserViewController. In other words, you can provide an iOS 11 Filesapp-like experience in your own apps. This is especially useful if your business model relies heavily on storing and manipulating information in flat files, like image files, audio files, video files, etc., or files that encode some kind of design representations, like CAD or vector graphics files.
I strongly encourage you to use Xcode to create a new project based on the iOS Document Based App template (see next section), review it thoroughly, and follow along with my steps in this tutorial. I’ll tell you when I customize the template code, show you what code I’ve edited or added, and explain my changes to the template code. Please follow along.

Starting with a Document Based App template

To get started, open Xcode and go to FileNew ->Project…, select iOS, and select the Document Based App template:
Click the Next button, fill out the usual new project details, and choose a location for your new project. You’ll notice later that I named my Document Based App template project “Document-Based App.” You’ll need to turn on Signing under your app target’s General settings tab.
Here’s the project file/bundle structure for the Document Based App template:
Here’s the storyboard that comes preconfigured with that same project template:

Configuring the document types your app will support

When you create Xcode projects that can manipulate files, there’s a bit of configuration you must do to tell the app what kind of files it can manipulate. For example, the Document Based App template app is minimally usable in terms of providing you with the Files app interface and allowing you to tap on and see a little meta data about image files (recognized by the “public.image” uniform type identifier or “UTI”). Apple decided that the template would support images, but I want to support text files, too.
Make sure the Document Based App template project you created is open in Xcode and:
  • go to the Project Navigator;
  • find and click on the project’s target;
  • select the Info tab;
  • scroll down to and find the Document Types section; and,
  • expand the Document Types disclosure triangle.
Here’s what you’ll see:
As I’d mentioned and as you can see in the previous image, your app is already configured to notice and open image type files. To add support for text files, click the plus (+) sign that I highlighted in blue in the previous image and fill in the various fields so that you have a second document type. The Document Types section will now have a new entry that looks like this:
If you prefer manipulating XML in your Info.plist file, you can add document type support for image and text files inside the main <dict> section:

Other preconfigured app options

The Document Based App template app comes preconfigured with its Info.plistcontaining the UISupportsDocumentBrowser key set to YES (or <true/> in XML). This is absolutely essential for your app to provide Files app-like behavior. You can read about this key here.
Since your app now declares the UISupportsDocumentBrowser key, that has the same effect as declaring the UIFileSharingEnabled and LSSupportsOpeningDocumentsInPlace key combination as discussed above in the section entitled “Opting your app into showing its files in the Files app.” You’ll be exposing your app’s files to the Files app and you’ll also be making those same files available to other developers’ apps. Think about it carefully before you write things like a user’s personal information or details about your own proprietary trade secrets into files that will be made possibly public.

The Implementation for a Files App-like Experience

I started with an Xcode iOS Document Based App template and customized it so that I could: 1) browse for, open, display, edit, and save UTF-8 encoded text files and 2)browse for, open, and display .PNG and .JPG image files. Let’s walk through my project code.

Browsing for and selecting documents with UIDocumentBrowserViewController

The preliminaries for browsing documents and opening documents are already configured for you in Xcode’s iOS Document Based App template. A user interface for navigating and selecting documents, identical to what the Files app provides, is furnished for you. You start coding when you want to add functionality for reading the contents of user-selected documents into a document model, editing contents, writing the edited contents back to the original file, writing contents to a new file name/path, creating new files, closing the original file, and a number of other operations.
I modified the Main.storyboard a bit later in the process of customizing the project template, especially the “Document View Controller” scene on the right. But we need to look at the scene on the left to get started, the “Document Browser View Controller” scene, whose backing class is DocumentBrowserViewController in file DocumentBrowserViewController.swift. Notice it has the Storyboard Entry Point:
App template file: DocumentBrowserViewController.swift
I’m going to describe my code in a series of steps — steps that are also comments in my code shown below. I’ll show you my code first, then describe the steps/comments.
I’ve only made minimal changes to the template code in DocumentBrowserViewController.swift, so I won’t show the original template, I’ll just show you my code and explain the comments I added:
#1.0 – When my app starts up, an instance DocumentBrowserViewController is created. That object, an instance of a subclass of UIDocumentBrowserViewController, is initialized via a callback to its viewDidLoadmethod. Notice it adopts the UIDocumentBrowserViewControllerDelegate protocol, whose main job is to notify the developer about user interactions with the document browser.
#1.1 – Set the delegate property of the UIDocumentBrowserViewControllerDelegate protocol to the DocumentBrowserViewController class. By doing so, the DocumentBrowserViewController class gets notified of user interactions with the document browser and UIDocumentBrowserViewControllerDelegate callbacks get invoked.
#1.2 – I commented out code to allow document creation, I left multiple document selection disabled, and left code for changing the appearance of the document browser commented out as it originally was as-is in the template. I didn’t want to get too fancy in this introductory tutorial.
#2.0 – When a user taps on a document icon in the browser interface, documentBrowser(_:didPickDocumentURLs:) is called. As Apple describes the process, “When the user selects one or more documents in the browser view controller, the system calls your delegate’s documentBrowser(_:didPickDocumentURLs:) method” with the URLcorresponding to the document icon that the user tapped/selected.
#2.1 – Then documentBrowser(_:didPickDocumentURLs:) calls the template project’s presentDocument(at documentURL: URL) method to give the developer a chance to prepare for and display the document’s contents, and/or display meta data about the document, and/or do something else with the selected document.
#3.0 – Prepare for and present my custom user interface which uses a UIDocumentsubclass to manipulate and/or display the user-select document.
#3.1 – Get the “Document View Controller” scene on the right side of Main.storyboard, which is backed by the DocumentViewController class, a subclass of UIViewController, in the DocumentViewController.swift file, and instantiate it. That’s my custom UI which we’ll discuss in detail later.
#3.2 – In the template project, the DocumentViewController class has a member document of type UIDocument, which is an “abstract base class.” According to Apple, “A document-based application must create a subclass of UIDocument for its documents.” An instance of my UIDocument subclass is initialized with the URL of the document that was selected by the user in my UI. My UIDocument subclass is initialized using init(fileURL: URL).
#3.3 – Finally, present(_:animated:completion:) is called and my customized UI, based on the work I did in Main.storyboard to add features to the DocumentViewController, and the work I did in DocumentViewController.swift, is displayed.

Opening, displaying, editing, closing the selected UIDocument

App template file DocumentViewController.swift contains a subclass of UIViewController which, in concert with its counterpart, the “Document View Controller” scene in Main.storyboard, provides a simple user interface for displaying the name of the document the user selected as described in the previous section. Notice that it declares a property document of type UIDocument while Apple admonishes us that “A document-based application must create a subclass of UIDocument for its documents.”
App template file: DocumentViewController.swift
Here’s the skeletal app template file as generated by Xcode:
I’ve extended and enhanced this file and its corresponding “Document View Controller” scene quite a bit. First, let me show you the user interface I built in the “Document View Controller” scene in Main.storyboard for viewing and editing documents:

Comments

Popular Posts

How I Reduced the Size of My React Native App by 85%

How and Why You Should Do It I borrowed 25$ from my friend to start a Play Store Developer account to put up my first app. I had already created the app, created the assets and published it in the store. Nobody wants to download a todo list app that costs 25mb of bandwidth and another 25 MB of storage space. So today I am going to share with you how I reduced the size of Tet from 25 MB to around 3.5 MB. Size Matters Like any beginner, I wrote my app using Expo, the awesome React Native platform that makes creating native apps a breeze. There is no native setup, you write javascript and Expo builds the binaries for you. I love everything about Expo except the size of the binaries. Each binary weighs around 25 MB regardless of your app. So the first thing I did was to migrate my existing Expo app to React Native. Migrating to React Native react-native init  a new project with the same name Copy the  source  files over from Expo project Install all de...

How to recover data of your Android KeyStore?

These methods can save you by recovering Key Alias and Key Password and KeyStore Password. This dialog becomes trouble to you? You should always keep the keystore file safe as you will not be able to update your previously uploaded APKs on PlayStore. It always need same keystore file for every version releases. But it’s even worse when you have KeyStore file and you forget any credentials shown in above box. But Good thing is you can recover them with certain tricks [Yes, there are always ways]. So let’s get straight to those ways. 1. Check your log files → For  windows  users, Go to windows file explorer C://Users/your PC name/.AndroidStudio1.4 ( your android studio version )\system\log\idea.log.1 ( or any old log number ) Open your log file in Notepad++ or Any text editor, and search for: android.injected.signing and if you are lucky enough then you will start seeing these. Pandroid.injected.signing.store.file = This is  file path where t...

React Native - Text Input

In this chapter, we will show you how to work with  TextInput  elements in React Native. The Home component will import and render inputs. App.js import React from 'react' ; import Inputs from './inputs.js' const App = () => { return ( < Inputs /> ) } export default App Inputs We will define the initial state. After defining the initial state, we will create the  handleEmail  and the  handlePassword  functions. These functions are used for updating state. The  login()  function will just alert the current value of the state. We will also add some other properties to text inputs to disable auto capitalisation, remove the bottom border on Android devices and set a placeholder. inputs.js import React , { Component } from 'react' import { View , Text , TouchableOpacity , TextInput , StyleSheet } from 'react-native' class Inputs extends Component { state = { ...