Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limiting UIActivityViewController share extension activities

I'm using UIActivityViewController with several custom UIActivityProviders. My providers return NSString, UIImage, and custom data objects. I exclude activities I don't want to share by setting UIActivityViewController excludedActivityTypes and Apple's Built-in Activity Types.

The thing I don't like are apps that appear on the presented UIActivityViewController that are not build in activity types. I'm assuming these appear because the apps have informed iOS 8 they can handle text and image data. Examples are Flickr, Evernote, and FaceBook's share extension. These activities have their own activity URL type that I don't want to hard code to.

The reason I don't want these apps in my activity sharing is most don't work properly, ending up giving my users a bad experience and likely blaming my app for poor implementation. The reality is that these apps don't handle the data they claim they can. For example, Evernote always just presents a empty post dialog. Some, like Facebook's share extension even log errors if they can't handle the data type (really?).

Is it possible to block all 3rd party sharing extensions?

If the answer is no, it seems I have only 2 options:

  • Only share with Apple's built in activities and my custom activities
  • Allow 3 party extensions to screw up the hand off
  • Wrap all my content in a custom class so it's not recognizable to extensions. This generates a logged error from Facebook

The difficulty comes from initWithPlaceholderItem:(id)placeholderItem. I pass back a generic NSString or UIImage which the extensions say they can handle but often don't or log an error on posting. This would be a horrible place to detect sharing extensions.

I want to provide my users with the most flexible sharing experience but not at the cost of poor 3rd party implementation.

I know we like to show code on SO but can't think of any that isn't just boilerplate UIActivityController fodder.

like image 532
Dan Avatar asked Dec 15 '14 16:12

Dan


1 Answers

Not sure it's smart to do so, but you can setup a "whitelist" of trusted activity providers. Then use UIActivityItemProvider with UIActivityItemSource protocol. You'll get calls on:

- (id)activityViewController:(UIActivityViewController *)activityViewController
     itemForActivityType:(NSString *)activityType

Check the activityType. If it's on your whitelist of trusted providers, return the data item. If the activityType isn't recognized, return nil (or return some neutered "safe" data element).

Untrusted activities may still show up in the Activity sheet, but they won't get data with which to cause a problem for your app.

like image 170
jbbenni Avatar answered Mar 03 '23 02:03

jbbenni