Different data for sharing providers in UIActivityViewController

I'm trying to use an UIActivityViewController with one long NSString as the data. If I put a string > 140 characters, the tweet sheet in it does not display the string. And if I truncate the string before giving it to the controller, all of the UIActivities have the truncated string. I don't want Facebook or Message to be truncated.

Is there a way to give different strings to different UIActivities?

Thank you!

(e.g. Marco Arment's The Magazine app does this by having a truncated string followed by @TheMagazineApp in UIActivityPostToTwitter, and other stuff in other UIActivities.)


I think this is what you're looking for: Custom UIActivityViewController icons and text.

You should be able to provide different data for each activity type.


Hope this helps somebody. It's pretty straightforward if you subclass UIActivityItemProvider:

@interface MyActivityItemProvider : UIActivityItemProvider
@end

@implementation MyActivityItemProvider

- (id)item
{
    // Return nil, if you don't want this provider to apply 
    // to a particular activity type (say, if you provide 
    // print data as a separate item for UIActivityViewController).
    if ([self.activityType isEqualToString:UIActivityTypePrint]) 
        return nil;

    // The data you passed while initialising your provider 
    // is in placeholderItem now.
    if ([self.activityType isEqualToString:UIActivityTypeMail] ||
        [self.activityType isEqualToString:UIActivityTypeCopyToPasteboard])
    {
        return self.placeholderItem;
    }

    // Return something else for other activities. Obviously, 
    // you can as well reuse the data in placeholderItem here.
    return @"Something else";
}

@end

Then pass its instance with an array of activity items to UIActivityViewController:

MyActivityItemProvider *activityItem = 
    [[MyActivityItemProvider alloc] initWithPlaceholderItem:@"Your data"];
NSArray *sharingItems = [NSArray arrayWithObjects:
    activityItem, _myUITextView.viewPrintFormatter, nil];

UIActivityViewController *activityController = 
    [[UIActivityViewController alloc] 
        initWithActivityItems:sharingItems applicationActivities:nil];

This can be easily done by using the optional activityType property from the UIActivityItemProvider object. That property returns a UIActivityType, so you can do something like:

class PhotoActivityItemProvider: UIActivityItemProvider {  
    ...

    override var item: Any {
        guard let activityType = self.activityType else {
            return photoURL.absoluteString
        }
        if activityType == .mail || activityType == .message {
            return "The photo link is \(photoURL.absoluteString)."
        }

        ...
    }

More information in my blog post: https://www.whitesmith.co/blog/control-what-youre-sharing/