TumblrArchive / ios-extension-issues

A collection of issues with iOS 8 share extensions, along with radar links, sample projects, and workarounds
204 stars 11 forks source link

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

Closed irace closed 9 years ago

irace commented 10 years ago

This is a doozy. It’s the most important issue we’ve found, and one that probably deserves a blog post of its own.

Here’s how applications pass data to share extensions:

Here’s how we think this should work, using the Tumblr app as an example:

What actually happens is that only share extensions that explicitly support images and URLs and text will show up.

This is a problem, because the simplest way to specify what your extension supports – and by far the best documented – is by adding NSExtensionActivationRule keys like:

`NSExtensionActivationSupportsText` : `YES`

This looks like it would mean “show my extension as long as any of the activity items are text,” but it really means “show my extension as long as there is only one activity item, and it is text.”

Federico Viticci, who at this point has likely used more third-party share extensions than anyone else on the planet, verifies that this is in fact a legitimate problem:

Workaround

This negatively affects both app and extension developers. It means that:

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

jesseditson commented 10 years ago

Some questions, specific to Tumblr:

I used to use the com.tumblr.photo UTI along with the TumblrTags and TumblrCaption metadata to send posts over to tumblr. I was hoping to be able to send a link and and image with the new extension, but it seems that in addition to being one or the other, it also doesn't have support for tags. Are you aware of any way to send metadata for custom fields over (in your case, tags)? Additionally, I noticed that your app no longer supports metadata with the UIDocumentInteractionController, so although I'm able to open your app, it doesn't initiate a post - we'd love to have that back for our iOS 7 users.

irace commented 10 years ago

I was hoping to be able to send a link and and image with the new extension

If putting both an NSURL and a UIImage in your activity items array doesn't give you the ability to create a photo post with the URL as the caption, it should. Thanks for the feedback, we'll see if we can make this possible.

It also doesn't have support for tags. Are you aware of any way to send metadata for custom fields over (in your case, tags)?

We could certainly support this, by asking you to create an object with a custom UTI that we specifically look for, and pull whatever different types of metadata that we want out of it. However, the problem with this approach is that only the Tumblr extension will show app, for the very reasons outlined in this issue. Other share extensions won't explicitly support the custom UTI, and as such, won't be displayed in the activity controller.

That said, we'd consider if there's enough demand for specialized, Tumblr-only activity controllers. I'd just be surprised if there was, is all.

Additionally, I noticed that your app no longer supports metadata with the UIDocumentInteractionController, so although I'm able to open your app, it doesn't initiate a post - we'd love to have that back for our iOS 7 users.

This certainly sounds like a bug. I'll file a ticket and take a look, thanks for bringing this to my attention.

paulrehkugler commented 10 years ago

we'd love to have that back for our iOS 7 users

Our container app with the share extension is iOS 8 only. Was this an issue with the last iOS 7 version?

jesseditson commented 10 years ago

That all makes a ton of sense to me - for now I'll concat the link & tags in to the text description. I didn't think to check if the new Tumblr was iOS 8, but that should resolve the old version, I'll add the extension support and fall back to the old one on iOS 7!

rileytestut commented 9 years ago

Did you ever have issues with the predicate simply being parsed incorrectly? I've written a very simple predicate string, yet the Photos app is miserably failing to evaluate it. For instance, you would assume this would allow my extension to be shown whenever a video file is being shared:

SUBQUERY (
    extensionItems,
    $extensionItem,

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

).@count >= 1

If you select a video in the photos app, and also select a photo that was taken after that video, the extension doesn't appear. However, here's the WTF part: if you select a video, and also a photo taken before that video, it does show up. I cannot come up with any reason why this would be the case, and unfortunately there doesn't seem to be a way to debug how the predicate is being parsed.

I've tried with screenshots, photos from the back camera and the front camera, it doesn't seem to make a difference. The only difference is whether they were taken before or after the shared video.

irace commented 9 years ago

This is fixed in iOS 9, as per the App Extension Best Practices session :tada:.

To opt your extension into OR instead of AND behavior, simply add the following key/value pair to your Info.plist:

NSExtensionActivationDictionaryVersion: 2
jasewells commented 9 years ago

The user long-presses on a photo We put the image data, the posts’s URL, and maybe a text summary of the post, all in the activity items array

Anyone know if the above is the actual behavior of the Tumblr app? I have an action extension that accepts an image, but cannot get it to show up when you long-press a photo. I’ve got NSExtensionActivationSupportsImageWithMaxCount = 1 and NSExtensionActivationDictionaryVersion = 2 in my Info.plist and my extension does appear when doing a similar share from Photos, Twitter, Flickr, etc. But Tumblr only seems to provide a public.url attachment type and nothing matching public.image. (And the link it provides is to the post, not a specific image.) So I’m just wondering if the above idea of providing an image, link, and text together is really being done or if that was just an example/idea and not actually how Tumblr provides activity items.

Incidentally, the standard system “Save Photo” and “Copy” actions do appear from Tumblr, so somehow they know there is image data?

paulrehkugler commented 9 years ago

You're right; that's not the behavior of the Tumblr app.

In order to avoid having photo posts be unable to be shared by share extensions that do not explicitly support images, we opted for what we assumed to be the lowest common denominator for all share extensions: URLs.

The system copy activity simply acts on the URL of the photo post; if you choose Copy and then paste in a text area, you'll see it's a URL.

The "Save Photo" activity is trickier. Because the system save image activity will not show up based on a URL, we wrote our own custom save image activity that we use when long pressing photos.

st3fan commented 7 years ago

@irace It looks like this behaviour again changed in iOS 11. In Firefox for iOS we now have half baked sharing support because our original predicate stopped working. Have you seen anything prblematic with iOS 11?

irace commented 7 years ago

Sorry – it’s been years since I’ve dealt with share extensions.

On Oct 18, 2017, 6:46 PM -0400, Stefan Arentz notifications@github.com, wrote:

@irace It looks like this behaviour again changed in iOS 11. In Firefox for iOS we now have half baked sharing support because our original predicate stopped working. Have you seen anything prblematic with iOS 11? — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.