24

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.)

etolstoy
  • 1,798
  • 21
  • 33
Mert Dümenci
  • 493
  • 1
  • 5
  • 18

4 Answers4

40

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.

ricardopereira
  • 11,118
  • 5
  • 63
  • 81
  • 3
    if you want to customize existing providers (FB, Twitter, etc) --> -(id) activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType - is the function you want to edit - this is where you decide which items will get published – Oded Regev Feb 19 '13 at 12:00
  • I don't get how you modify facebook/twitter etc text independently from this... do you have to initialize an APActivityProvider for each one that you want to be different? – shim Nov 12 '13 at 04:23
  • http://stackoverflow.com/questions/26451583/uiactivityview-controller-behaviour-is-strange – Mian Muhammad Umair Liaqat Oct 19 '14 at 14:44
  • I've Upgraded my project to SDK 9.x and received ( 'init' is unavailable ) error on APActivityProvider *ActivityProvider = [[APActivityProvider alloc] init] how can i fix this ? – OXXY Jan 10 '16 at 11:58
11

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];
Dmitry
  • 376
  • 3
  • 15
2

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/

ricardopereira
  • 11,118
  • 5
  • 63
  • 81
0

You can create a class that conforms to UIActivityItemSource and then pass its instance with an array of activity items to UIActivityViewController:, as @Mu-Sonic suggested.

If you want to know in which platform is the user sharing and return any specific data dependent on the tapped platform, override public func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any?

Adriana
  • 806
  • 11
  • 36