How to customize share sheet content for AirDrop

Or other share destinations, like adding to a reading list.

Published: Dec. 30, 2022
App Store

Some time ago, I changed how articles are shared in my SwitchBuddy app. Originally the app just shared the URL, but I changed it to share the article title, website, and SwitchBuddy attribution + the link in single text (represented with plain string).

Sharing text works great for messaging apps and social media. Only when I shared an article to my Mac via AirDrop did I spot the problem.

Instead of my Mac opening the article in a browser, it saved a text file containing the entire text. This makes sense, but it is not a good experience.

Thankfully we can customize what gets shared based on the user's selected option or “destination”.

This requires adopting a specific protocol and the implementation of a few methods.

Meet UIActivityItemSource

The protocol is called UIActivityItemSource and it, unfortunately, requires a class object that inherits from NSObject. Since I usually use structs, I created a special class for sharing. I think it makes the “logic” nicely encapsulated.

You can do a lot with this protocol; however, for this post, we are only concerned about sharing a different piece of data when the user selects AirDrop from the share sheet.

Conforming to this protocol requires the implementation of these two methods:

func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
}

func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
}

The placeholder method is there when you want to share remote content represented with a URL for which iOS needs to fetch a preview.

These two methods are all we need to implement this. My class for sharing has properties shareText, which is the string I mentioned, and url, which contains the link to the article I am sharing.

For the placeholder, we can use the text like this:

func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
    return shareText as Any
}

The class can then be used like this:

let ac = UIActivityViewController(activityItems: [shareItem], applicationActivities: nil)

Customize sharing for AirDrop

And if you look at the second method's signature, there is an optional activityType parameter. This parameter tells us what activity the user selected. We can check if the action happens to be AirDrop or something else and behave accordingly.

func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
    if activityType == .airDrop || activityType == .addToReadingList {
        return url
    } else {
        return shareText
    }
}

I am also checking for the addToReadingList activity, which adds the URL to the Safari’s reading list. It does not make sense to provide the text here.

And that is it!

Filip Němeček profile photo

WRITTEN BY

Filip Němeček @nemecek_f@iosdev.space

iOS blogger and developer with interest in Python/Django. Want to see most recent projects? 👀

iOS blogger and developer with interest in Python/Django. Want to see most recent projects? 👀