UIActivityViewController workaround to ‘Share in WhatsApp’ in iOS

UIActivityViewController was introduced in iOS 6 as a helper to share texts, links or images between apps.

It’s really easy to work with default services (share on Twitter, Facebook, Mail…), and since several iOS versions, it’s also integrated with third-party apps like Slack or Telegram.

Use it is simple, you only need to create and present a UIActivityViewController as follows:

UIViewController *root = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
UIActivityViewController *activityView = [[UIActivityViewControllerWithoutWhatsApp alloc] initWithActivityItems:shareObject applicationActivities:nil];
[root presentViewController:activityView animated:YES completion:nil];

A typical setup looks like that, but sometime you don’t want to allow to send SMS, or Mails from your action, so you can set an array of excludedActivityTypes as follows:

activityView.excludedActivityTypes = @[UIActivityTypeMessage, UIActivityTypeMail];

There are several ‘built-in’ activities, but you can craft yourself UIActivity to do specific actions, a good compilation is available in Github/UIActivityCollection.

In our case, and because we suffered a bug related with last WhatsApp version, which showed a message when try to share with one of your whatsapp contacts:

This item cannot be shared. Please select a different item.

We decided to workaround it using URLSchemes, and we found SSCWhatsAppActivity, a UIActivity subclass which shows an icon on share menu, but it appeared next to the original whatsapp icon, so we needed to remove this first.

As logic indicated, we looked for whatsapp activity identifier, and add to excludeActivityTypes array as follows:

activityView.excludedActivityTypes = @[@"net.whatsapp.WhatsApp.ShareExtension"];

But it’s not possible to remove third-party activities from menu, at least directly.
So, after play some minutes with <objc/runtime.h>, we finally found a private method which seemed to be related with our purpose: _shouldExcludeActivityType:

We decided to create a UIActivityViewController subclass which overrides that method, and use it to show menu instead of original:

#import "UIActivityViewControllerWithoutWhatsApp.h"


@interface UIActivityViewController (Private)
- (BOOL)_shouldExcludeActivityType:(UIActivity*)activity;
@end


@implementation UIActivityViewControllerWithoutWhatsApp
- (BOOL)_shouldExcludeActivityType:(UIActivity *)activity
{
if ([[activity activityType] isEqualToString:@"net.whatsapp.WhatsApp.ShareExtension"]) {
return YES;
}

return [super _shouldExcludeActivityType:activity];
}
@end

And, you know what? It works! Thanks Apple to do that so straightforward.

Like what you read? Give Jorge Maroto a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.