iosswiftuiinfo.plist

How do iOS apps directly launch on tapping a document in Files or Messages instead of just with Open In?


My SwiftUI scene-based app has .onOpenURL() implemented and I can successfully open my custom file type that is "shared" with it. But, since I'm the only app for my custom file I want my app to just launch on tapping the file. This is not a "document-based app"

If you have a .xlsx or even generic .csv document in Files and the Excel app installed, tapping the document switches directly to the full Excel app, without Files showing a blank placeholder then needing to press the share button.

Here is my relevant info.plist:

<key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeName</key>
            <string>My App Document</string>
            <key>LSHandlerRank</key>
            <string>Owner</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.myappname.tc-document</string>
            </array>
        </dict>
    </array>

and custom Exported UTI:

<key>UTExportedTypeDeclarations</key>
    <array>
        <dict>
            <key>UTTypeConformsTo</key>
            <array>
                <string>public.data</string>
            </array>
            <key>UTTypeDescription</key>
            <string>My App Document (tc)</string>
            <key>UTTypeIconFiles</key>
            <array/>
            <key>UTTypeIdentifier</key>
            <string>com.myappname.tc-document</string>
            <key>UTTypeReferenceURL</key>
            <string></string>
            <key>UTTypeTagSpecification</key>
            <dict>
                <key>public.filename-extension</key>
                <array>
                    <string>tc</string>
                    <string>TC</string>
                </array>
            </dict>
        </dict>
    </array>

So far I have tried adding to the CFBundleDocumentTypes:

            <key>CFBundleTypeRole</key>
            <string>Editor</string>

But this didn't seem to change anything, and then I got a

The application supports opening files, but doesn't declare whether it supports opening them in place. You can add an LSSupportsOpeningDocumentsInPlace entry or an UISupportsDocumentBrowser entry to your Info.plist to declare support.

warning from the compiler.

Also interesting is I can use Open-In from a mail attachment, but if I send my file as an iMessage I can't even launch Open-In and thus can't do anything with it from Messages.


Solution

  • To implement all of the features on iOS:

    1. There is no need for the CFBundleTypeRole key, it seems to be for Mac apps.

    2. Add the <key>LSSupportsOpeningDocumentsInPlace</key> <true/> key to the main dict in info.plist, which will make files you tap open directly in the app as well as regular Open-In.

    3. To add the support for opening documents in place, implement a subclass of UIDocument. At the minimum, add the init(url: URL) and override func load(fromContents contents: Any, ofType typeName: String?). The UIDocument will handle whether the url is security scoped or not, so no need to call .startAccessingSecurityScopedResource() yourself. The UIDocument will also handle asynchronously waiting for an iCloud Drive file to download.

    4. In the .onOpenURL { url in } or elsewhere call your UIDocumentSubclass(url: url).open(completionHandler:)