UIActivityViewController - Only attach a URL for certain activities

ios, objective-c, uiactivityviewcontroller, url, xcode

Solution

You can choose what to send to each type of activity. I created a custom activity provider and call it like this:

     NSMutableArray *activityItems = [NSMutableArray array];

     CustomActivityItemProvider *activityItemProvider =
     [[CustomActivityItemProvider alloc] initWithText:text
                                                     urlText:urlString];

     [activityItems addObject:activityItemProvider];


     //you can have your own custom activities too:
     NSArray *applicationActivities = @[[CustomActivity new],
                                              [OtherCustomActivity new]];
     UIActivityViewController *vc = [[UIActivityViewController alloc]initWithActivityItems:activityItems
                                                                     applicationActivities:applicationActivities];

The custom provider is a subclass of UIActivityItemProvider

@interface CustomActivityItemProvider : UIActivityItemProvider

- (id)initWithText:(NSString *)text urlText:(NSString *)url;

@end

The guts of my custom provider class look something like this:

- (id)initWithText:(NSString *)text urlText:(NSString *)url{

    if ((self = [super initWithPlaceholderItem:text])) {       
        self.text = text ?: @"";
        self.url = url ?: @"";
    }   
    return self;
}

- (id)item {   
    NSString *activityType = self.activityType;
    if ([self.placeholderItem isKindOfClass:[NSString class]]) {            
        if ([self.activityType isEqualToString:UIActivityTypePostToFacebook] ||
            [self.activityType isEqualToString:UIActivityTypeMail]) {

            return [NSString stringWithFormat:@"%@\n%@", self.text, self.url];

        } else if ([activityType isEqualToString:UIActivityTypePostToTwitter]) {

            return [self findBestStringOfLength:kTwitterMessageLength hashTags:YES];

        } else if ([activityType isEqualToString:UIActivityTypeMessage]) {

            return [self findBestStringOfLength:kSMSMessageLength hashTags:YES];

        } else {
            return self.text;
        }
    }

    return self.placeholderItem;
}

Problem

I've been trying to use the new UIActivityViewController to replace all of my UIActionSheets for sharing, however I've run into an issue. I have 5 activities, Message, Email, Copy, Twitter, and Facebook. I've already figured out how to have those show different text, through this in a custom UIActivityProvider subclass: ``` - (id) activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType { if ( [activityType isEqualToString:UIActivityTypePostToTwitter] ) return twitter; if ( [activityType isEqualToString:UIActivityTypePostToFacebook] ) return facebook; if ( [activityType isEqualToString:UIActivityTypeMessage] ) return urlScheme; if ( [activityType isEqualToString:UIActivityTypeMail] ) return urlScheme; if ( [activityType isEqualToString:UIActivityTypeCopyToPasteboard]) return urlScheme; return nil; } ``` And this in my view controller: ``` ActivityProvider *aProvider = [[ActivityProvider alloc] init]; aProvider.facebook = facebook; aProvider.twitter = twitter; aProvider.urlScheme = URL; NSArray *Items = @[aProvider, sharedURL]; UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:Items applicationActivities:Nil]; activityVC.excludedActivityTypes = @[UIActivityTypePrint, UIActivityTypeAssignToContact,UIActivityTypeSaveToCameraRoll, UIActivityTypePostToWeibo]; [self presentViewController:activityVC animated:TRUE completion:nil]; ``` However, I only want to show the URL (sharedURL) in the Facebook and Twitter share sheets, not the message, email or copy. Any way to accomplish this?

Original source