As you may know, the apps installed on iOS, for security reasons, are confined to the App Sandbox. This means that from an iOS App, you can access only files generated by the app itself or included in the app folder.
To help the developers, UIKit provides two standard UI solutions on iOS to access files from the app folder and from Cloud providers:
- The UIDocumentBrowserViewController is the apple standard View Controller to manage documents on iOS and navigate through cloud resources and performing actions on them.
- The UIDocumentPickerViewController is the standard View and has been designed for importing, exporting, opening, or moving files.

Documentation and Tutorials
Apple has provided very good examples on how to use them and I suggest you read the official documentation to learn how to use them:
UIDocumentBrowserViewController
- Adding a document browser to your app
- Setting Up a Document Browser App
- Presenting Selected Documents
- Enabling Document Sharing
- Building a Document Browser App for Custom File Formats
UIDocumentPickerViewController
WWDC
https://developer.apple.com/videos/play/wwdc2018/216/
My Use Case: GPX Track Viewer
The classical use case for UIDocumentBrowserViewController is as a viewer for a specific file type.
For example, I used it to build an app called Trackyzer Pro, a GPX viewer for cyclists with rich graphics for slope, speed, and altitude data. The app can save a workout as GPX or open any GPX file with a track using the Document Browser.

Greyed Icons
I built my app following the best practices and tutorials provided by Apple and everything seemed correct until I installed my app in a real device.
Now, most of the cyclists have more than one app to import GPX files and the result is that on some occasions the Document Browser inside the app shows greyed icons.
Once the icons are greyed out in the Document Browser, the user cannot open any file from the app.

Digging a little bit more on the issue I came across this post on the support blog:
“We understand that you are having issues with your type definition for .gpx files. At this time, there is no commonly-accepted Uniform Type Identifier for .gpx files and different developers have defined their .gpx declaration differently. This means that if two apps are installed on the same device that claim to open these files with different definitions, they won’t interact correctly: from the user’s point of view, only one of those apps, chosen seemingly at random, will be able to open these files.”
The GPX format is defined here and it’s an XML text file. So in different conditions, depending on which app the user has installed, iOS may display it as a Text icon, an XML icon, or a custom icon.
It seems there is no solution to the issue, but I found one.
What is a Uniform Type Identifier?
According to Apple official documentation, a Uniform Type Identifier:
“is a string that uniquely identifies a class of entities considered to have a “type.” For example, for a file or other stream of bytes, “type” refers to the format of the data. For entities such as packages and bundles, “type” refers to the internal structure of the directory hierarchy. Most commonly, a UTI provides a consistent identifier for data that all applications and services can recognize and rely upon, eliminating the need to keep track of all the existing methods of tagging data.”
Examples of UTI for GPX as declared in Info.plist
:
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.content</string>
<string>public.data</string>
<string>public.xml</string>
</array>
<key>UTTypeDescription</key>
<string>GPS Exchange Format (GPX)</string
<key>UTTypeIconFiles</key>
<array>
<string>GPX.icns</string>
</array>
<key>UTTypeIdentifier</key>
<string>com.topografix.gpx</string>
<key>UTTypeReferenceURL</key
<string>http://www.topografix.com/GPX/1/1</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>gpx</string>
</array>
<key>public.mime-type</key>
<array>
<string>application/gpx+xml</string>
</array>
</dict>
</dict>
This essentially states that a GPX file could be:
- A file with the extension
.gpx
- A mime type
application/gpx+xml
- A document conforming to
public.xml, public.text, public.data
with the following reference url:[http://www.topografix.com/GPX/1/1](http://www.topografix.com/GPX/1/1)
… but anyone can define their own UTI. In this way, there is no easy way to get the owner of the type for an App.
How Do I Know if Another App Is Using My UTI?
Apple provides a function to get the preferred UTI for a type UTTypeCreatePreferredIdentifierForTag:
func preferredUTI(ext: String) -> String? {
let theUTI = UTTypeCreatePreferredIdentifierForTag(
kUTTagClassFilenameExtension,
ext as CFString,
nil)?.takeRetainedValue()
return theUTI as String?
}
If you’ll use it, you’ll discover that the icons are greyed out when there is a preferred UTI declared by another app.
It’s possible to know all the UTIs declared in your system by using the function UTTypeCreateAllIdentifiersForTag.
The following example implements a way to get all the UTI identifiers for a specific file extension:
func getUTTypeCreateAllIdentifiers(for tag: String) -> [String] {
let cfArray = UTTypeCreateAllIdentifiersForTag(
kUTTagClassFilenameExtension,
tag as CFString,
nil
)?.takeRetainedValue()
let utis:[String] = cfArray as? [String] ?? []
return utis;
}
Note: These functions are deprecated in iOS14, but there is a new type called UTTypeReference in which you’ll find the equivalent methods.
Greyed Out Icon: The Solution
Now that we understand what’s going on, let’s find a solution.
Reading the documentation of the classes you’ll spot this on UIDocumentBrowserViewController:
init(forOpeningFilesWithContentTypes allowedContentTypes: [String]?)
allowedContentTypes
An array of uniform type identifiers (UTIs). The document browser can open only the document types specified by these UTIs. If you passnil
, the browser uses the document types specified by theCFBundleDocumentTypes
key in the app’sInfo.plist
file
and for UIDocumentPickerViewController:
init(documentTypes allowedUTIs: [String], in mode: UIDocumentPickerMode)
allowedUTIs
An array of uniform type identifiers (UTIs). UTIs are strings that uniquely identify a file’s type.
Apple examples are prepared with Storyboards, which means that the UIDocumentBrowserViewController is instantiated with a default implementation, meaning nil
is passed as allowedContentTypes
, this will filter the files only with the UTI you have declared, but not with the preferred UTI declared by another app.
If you pass all the UTIs in the init method the issue is solved, as the filter applied it’s not just what you defined in the CFBundleDocumentType
, but also it includes all the UTIs registered.
//UIDocumentViewController
let utis = func getUTTypeCreateAllIdentifiers(for: "gpx")
let viewController = UIDocumentViewController(forOpeningFilesWithContentTypes: utis)
//UIDocumentPickerViewController
let viewController = UIDocumentPickerViewController(documentTypes: utis, in: .open)

Conclusions
This article covered a specific issue that it’s not so evident by reading the official documentation.
The potential use of these two components is quite amazing, but the challenge is to configure them in the right way.
It’s possible to add specific actions and different styles, it’s possible to preview documents and share them. I leave to you the adventure of exploring more options.
Thanks for reading.
