12

I'm having a problem with my app's iOS Share Extension. I have the following code in the Share Extension Info.plist.

<key>NSExtension</key>
<dict>
    <key>NSExtensionAttributes</key>
    <dict>
        <key>NSExtensionActivationRule</key>
        <dict>
            <key>NSExtensionActivationSupportsWebPageWithMaxCount</key>
            <integer>1</integer>
            <key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
            <integer>1</integer>
        </dict>
    </dict>
    <key>NSExtensionMainStoryboard</key>
    <string>MainInterface</string>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.share-services</string>
</dict>

The major problem is the extension doesn't show up in Google Chrome, NYTimes, WSJ, and many other apps. All of which should provide either a Web Page or Web URL.

I read somewhere that I have to add the following to the NSExtensionActivationRule dict.

<key>NSExtensionActivationSupportsText</key>
<true/>

If I add then the share extension appears in the apps listed above but just returns a string to my extension. For example if I go to apple.com in Google Chrome and use my share extension it just provides Apple as a string to my extension which my app doesn't really support. It should be providing some type of URL or something along those lines. And in the NYTimes app it would just send the headline of the article to the extension.

The extension works perfectly in Safari. Just not certain 3rd party applications.

Below is the main code for receiving the URL in the swift file of my extension.

if let item = extensionContext?.inputItems.first as? NSExtensionItem {
    if let itemProvider = item.attachments?.first as? NSItemProvider {
        if itemProvider.hasItemConformingToTypeIdentifier("public.url") {
            itemProvider.loadItem(forTypeIdentifier: "public.url", options: nil, completionHandler: { (url, error) -> Void in
                if let shareURL = url as? NSURL {
                    print (shareURL.absoluteString!)

From there I handle the URL as my application should.

When I added the NSExtensionActivationSupportsText option I changed the code above slightly from public.url to public.text along with a few other things to test it and it was just returning super unhelpful strings.

I know this is possible to get the URL from those applications because even in NYTimes it has an option for Google Chrome, which defiantly needs a URL and not just the article headline. Any ideas on how to get that URL?

Charlie Fish
  • 18,491
  • 19
  • 86
  • 179

1 Answers1

8

I would suggest you to use this:

    <key>NSExtension</key>
<dict>
    <key>NSExtensionAttributes</key>
    <dict>
        <key>NSExtensionActivationRule</key>
        <string>
  SUBQUERY (
      extensionItems,
      $extensionItem,
      SUBQUERY (
          $extensionItem.attachments,
          $attachment,
          ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.url"
      ).@count == 1
  ).@count == 1
        </string>
    </dict>
    <key>NSExtensionMainStoryboard</key>
    <string>MainInterface</string>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.share-services</string>
</dict>

Considering your code to get the attachments, you are checking just first inputItems and first attachment, you need to have foreach loop in both cases and check all of them.

Ivan Ičin
  • 9,672
  • 5
  • 36
  • 57
  • Getting the following error message with your code example: `(null): couldn't parse contents of ' Share Extension/Info.plist': The data couldn’t be read because it isn’t in the correct format.`. Would also be helpful if you could provide more detail and explain why that code might work. Not sure if it does work yet since it gives that error message. – Charlie Fish May 04 '17 at 23:36
  • @CharlieFish this is copied from my project from Xamarin on Windows. It could be that Windows line feed characters cause that problem, so try to copy line by line, though it should work as the final version compiles on Mac with Xcode properly. You have probably did something wrong with copy and paste. – Ivan Ičin May 04 '17 at 23:39
  • @CharlieFish considering explanation - Chrome just doesn't set data in that format. For Chrome you need to add one more data format (plain text I believe). But even that won't work for all apps, e.g. Apple News. This tells the app to work as long as there is really just one attachment with URL. – Ivan Ičin May 04 '17 at 23:47
  • Ok so now it's displaying in Chrome at least. Only problem is `itemProvider.hasItemConformingToTypeIdentifier("public.url")` returns false. So how can I get the URL then? – Charlie Fish May 04 '17 at 23:51
  • @CharlieFish you are checking just first attachment, you need to make foreach loop and check all attachments. – Ivan Ičin May 04 '17 at 23:54
  • That looks like it worked! Thank you so much!! I'm going to wait to mark as accepted answer and award the bounty until the bounty is over (in case someone gives a better answer). Thanks so much!! – Charlie Fish May 05 '17 at 00:32
  • This only worked for some sites for us after the iOS 14 upgrade. On iOS 14 we only saw the share extension showing in the second attempt. We had to change both `@count` comparisons to `@count > 0` to get the share extension to consistently show on all sites. – jmif Nov 05 '20 at 21:04