I have an iOS app with an action extension that is used to perform actions on images inside other apps when they present UIActivityViewController
. Everything is working as intended - if I present an activity sheet in another app, my action extension appears in the list alongside the system actions (such as Save to Files and Create Watch Face etc).
However, the action extension also appears in my own app when I present UIActivityViewController
on an image there, which I do not want to happen. Is there any way to prevent my own action extension from appearing in UIActivityViewController
inside my own app?
I've tried adding an entry to excludedActivityTypes
when presenting UIActivityViewController
as follows, but this did not work:
let activity = UIActivityViewController(activityItems: [media], applicationActivities: nil)
activity.excludedActivityTypes = [UIActivity.ActivityType("com.example.ActionExtensionIdentifier")]
// other setup code
present(activity, animated: true)
Here's the solution that I finally used, in case anyone else needs this. (The code was taken from this blog post: https://pspdfkit.com/blog/2016/hiding-action-share-extensions-in-your-own-apps/ so take a look at that too for more details, but the solution I've provided here contains everything that is required to make this work.)
1. First, create this class
class ActionExtensionBlockerItem: NSObject, UIActivityItemSource {
func activityViewController(_ activityViewController: UIActivityViewController, dataTypeIdentifierForActivityType activityType: UIActivity.ActivityType?) -> String {
return String()
}
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
return NSObject()
}
func activityViewController(_ activityViewController: UIActivityViewController, subjectForActivityType activityType: UIActivity.ActivityType?) -> String {
return String()
}
func activityViewController(_ activityViewController: UIActivityViewController, thumbnailImageForActivityType activityType: UIActivity.ActivityType?, suggestedSize size: CGSize) -> UIImage? {
return nil
}
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
return String()
}
}
2. Apply instance of that class
When you present UIActivityViewController
, create an instance of ActionExtensionBlockerItem
and include it in the activityItems
array like this:
func share(_ image: UIImage) {
let activity = UIActivityViewController(activityItems: [image, ActionExtensionBlockerItem()], applicationActivities: nil)
activity.popoverPresentationController?.sourceView = view // change to something appropriate for your app
activity.popoverPresentationController?.sourceRect = view.bounds // change to something appropriate for your app
present(activity, animated: true)
}