How to share things with a UIActivityViewController

Screen Shot 2015-10-17 at 15.13.52

Since iOS 6 it has been really easy to share many complex objects, thanks to the UIActivityViewController. All we have to do is wrap our object (or objects) in an array, give that to the activity view controller, and present it.

To share a UIImage on iPhone for example, we’ll do something like this:

We need the array because we could be sharing more than just one item. The result looks something like the screenshot above: two rows of shareable icons appear, the top one representing “share” options, and the bottom one representing “action” options. Each of these is a UIActivity object. If ever you need to create your own activities, you can add them to either top or bottom category (but we won’t cover how to do that here).

On iPad, this type of presentation will crash – and Apple would like us to use a Popover presentation instead. It gets a bit long to show this here every time, so I’ve refactored this call into its own method and will be referring to it going forward:


Excluding certain activities

If called as mentioned above, iOS will compile a list of all possible activities our item can be shared as. UIImages for example could be saved to our Photo Library, Air-dropped, Facebooked or emailed, among other things.

To trim this list down to something more relevant, we can exclude certain activities. Imagine we don’t want the option to share on Facebook and Twitter, we can do it like this:

The UIActivity class has a type property, each of which is an NSString, and Xcode knows them all. You can literally exclude anything and everything from this list (check the class reference below for all types you can include here).

Reacting to user selections

The UIActivityViewController calls a completion handler block we can access. In it we’re given the activity  the user selected (as reverse-domain string), a BOOL ti indicate if the user used a sharing option (YES) or if the cancel button was pressed (NO), and error object and possible returned objects.

Sadly the Apple documentation isn’t very obvious how to do this at the time of writing, and it took some tinkering to find this out:

In essence, we need to create our own block through which the above objects are available, and add it to our controller. It’s slightly different from using a block that’s part of a method signature or implementing delegate methods – but this approach works just the same.

The activityType will be something like, through which you can test which activity was selected by the user. If the completed BOOL returns NO, the cancel button was pressed.

Demo Project

I’ve got a working demo project on GitHub. Feel free to take a look at it:

Further Reading

About Jay Versluis

Jay is a medical miracle known as Super Survivor. He runs two YouTube channels, five websites and several podcast feeds. To see what else he's up to, and to support him on his mission to make the world a better place, check out his Patreon Campaign.

9 thoughts on “How to share things with a UIActivityViewController

  1. Well presented. One thing I’m a problem with is sharing UIImages through email on the iPad. Everything else works fine. But specifically sharing over email on an iPad makes it just return with “completed” set to NO as soon as user taps the Mail icon. Very strange that I can’t seem to find any mention off it by anyone else.

  2. Hy,

    Using Xcode 8.3.3 and iPad (10.3.3), the image sharing does not work at all (there is just no image .. even not a blank or corrupted image ..)
    If you have any idea ?

    Anyway, thank you for your code !


    1. Hi Tux,

      I did some investigating, and the demo code runs fine as is on my iOS 9 device, sharing an image to the camera roll without a hitch. On iOS 10 however, I got a crash with the following explanation:

      After fixing that, it shared the image as it should. I’ve explained how to add this key here:

      I’ve also updated my Demo Project to include this key now, it should work fine with iOS 10 now.

  3. I got the error:-
    No visible @interface for ‘XXXX’ declares the selector ‘presentViewController:animated:completion:’

    1. Hi Ali, it’s difficult to diagnose this without seeing your code, but this error generally indicates that the class you’re calling this method on is not a child of the UIViewController class. For example, if I inherit my class from NSObject and call presentViewController:animated:completion on it, that error springs up (because my class doesn’t know that method, unless I define it myself, or unless the parent class has defined it). It’s possible that you’re calling the method on self, and self isn’t a view controller.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.