Search code examples
iosshare-extension

Share extension does not appear in capable apps if NSExtensionActivationRule is set for audio only


I am trying to create a share extension where the users can upload her audio recordings from any capable app. The documentation even has a straightforward example (see Declaring Supported Data Types for a Share or Action Extension) (also brought up in this SO answer), but it does not work in any audio recorder (on iOS 10.3.3, iPad).

Looking at the Uniform Type Identifiers Reference, I need public.audio. The relevant entry in the share extension's Info.plist:

![enter image description here

To narrow it down, I tried changing NSExtensionActivationRule to public.mpeg4 and public.audiovisual-content, same results.

When I change the NSExtensionActivationRule to conform to public.image though, it shows up in photo apps:

SUBQUERY (
    extensionItems,
    $extensionItem,
    SUBQUERY (
        $extensionItem.attachments,
        $attachment,
        ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image"
    ).@count == $extensionItem.attachments.@count
).@count == 1

Changing NSExtensionActivationRule to TRUEPREDICATE string would make it to finally show up in audio apps as well, but of course, this wouldn't be accepted in the App Store.

I also tried every above step on a clean start (i.e., clean + clean build folder + delete DerivedData contents + remove app from iPad), but the results where the same.

This SO question also seemed relevant, but changing the share extension's deployment target didn't help.

Am I missing something?


Solution

  • NOTE: As Jamshed Alam states in his comment, changes in iOS 13 make this answer obsolete.

    My share extension would allow uploading audio files to a Firebase backend, and I naively assumed that audio recording apps would appropriately declare their supported file types, but they don't. Most conform to multiple uniform type identifiers (see reference) with public.data being the most common.

    I found this Github issue from 2014 and used it as a reference. Its title perfectly summarizes the problem:

    Share extensions will only show up if they explicitly support all of the provided activity items

    The solution of using NSExtensionActivationDictionaryVersion worked for me too. According to Information Property Key List Reference:

    Activation dictionary version 1 Only when the app extension handles all of the asset types being offered by a host app item provider

    Activation dictionary version 2 When the app extension handles at least one of the asset types being offered by a host app item provider

    My share extension's Info.plist looks like this now:

    <key>NSExtension</key>
    <dict>
        <key>NSExtensionAttributes</key>
        <dict>
            <key>NSExtensionActivationRule</key>
            <dict>
                <key>NSExtensionActivationDictionaryVersion</key>
                <integer>2</integer>
                <key>NSExtensionActivationSupportsAttachmentsWithMinCount</key>
                <integer>1</integer>
                <key>NSExtensionActivationSupportsFileWithMaxCount</key>
                <integer>20</integer>
            </dict>
        </dict>
        <key>NSExtensionMainStoryboard</key>
        <string>MainInterface</string>
        <key>NSExtensionPointIdentifier</key>
        <string>com.apple.share-services</string>
    </dict>
    

    Or in Xcode:

    enter image description here

    Using only NSExtensionActivationSupportsFileWithMaxCount besides NSExtensionActivationDictionaryVersion would probably have sufficed.