0

I am implementing UIActivityViewController to share text and image through other apps. My problem starts when WhatsApp doesn't accept text and image together, so I want to remove text (if exists) when user chooses to share with WhatsApp.

How can I remove some activity items after the destination app was choosen in UIActivityViewController?

Thomás Pereira
  • 9,589
  • 2
  • 31
  • 34

1 Answers1

1

First of all, you need to create a class that conforms to UIActivityItemSource, and use it instead of passing the text or image directly to UIActivityViewController.

So instead of

UIActivityViewController(activityItems: [image, text])

We would pass the new item sources

UIActivityViewController(activityItems: [ImageItemSource(image), TextItemSource(text)]

The item source classes will look something like this:

class TextItemSource: NSObject, UIActivityItemSource {
    private let text: String

    init(text: String) {
        self.text = text
        super.init()
    }

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

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

class ImageItemSource: NSObject, UIActivityItemSource {
    private let image: UIImage

    init(image: UIImage) {
        self.image = image
        super.init()
    }

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

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

Now that we have control over what we'll share, we can choose what exactly we share with each app by checking activityType before returning the data, and if we think we should not send anything at all, we can simply return nil.

In your case, if you want to share the text item with all apps except WhatsApp, you can simply do this:

class TextItemSource: NSObject, UIActivityItemSource {
    ...
    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
        if activityType?.rawValue.starts(with: "net.whatsapp.WhatsApp.") == true {
            // We'll return `nil` to WhatsApp forcing it to 
            //   ignore this whole text item and only show the image item instead
            return nil
        }

        return text
    }
    ...
}
Hejazi
  • 16,587
  • 9
  • 52
  • 67