10

Finally been making it through Apple's (rather dismal) documentation on the new UIActivityViewController class and the UIActivityItemSource protocol, and I'm trying to send different data sets to different actions called from the activity view. To simplify things, I'm looking at two things.

  1. A Facebook posting action, which should say "Check this out!" and also attach a URL to the post (with that cute little paperclip).
  2. A Twitter posting action, which should say "Check this out, with #hashtag!" and also attach that same URL (with the same paperclip).

Here's the code I've got implemented right now.

- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType {
    if ([activityType isEqualToString:UIActivityTypePostToFacebook]) {
        return @"Check this out!";
    } else if ([activityType isEqualToString:UIActivityTypePostToTwitter]) {
        return @"Check this out, with #hashtag!";
    }

    return @"";
}

- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController {
    return @"";
}

And then when I set up this activity view controller (it's in the same class), this is what I do.

UIActivityViewController *activityView = [[UIActivityViewController alloc] initWithActivityItems:@[self] applicationActivities:nil];
[self presentViewController:activityView animated:YES completion:nil];

My dilemma is how to attach that NSURL object. It's relatively easy when calling the iOS 6 SL-class posting modals; you just call the individual methods to attach a URL or an image. How would I go about doing this here?

I'll note that instead of returning NSString objects from -activityViewController:itemForActivityType, if I return just NSURL objects, they show up with that paperclip, with no body text in the post. If I return an array of those two items, nothing shows up at all.

Ben Kreeger
  • 6,355
  • 2
  • 38
  • 53

1 Answers1

15

Evidently it was as simple as this: passing in an array to the first argument of UIActivityViewController's init call, with each item in the array handling a different data type that will end up in the compose screen. self handles the text, and the second object (the NSURL) attaches the URL.

NSArray *items = @[self, [NSURL URLWithString:@"http://this-is-a-url.com"]];
UIActivityViewController *activityView = [[UIActivityViewController alloc]  initWithActivityItems:items applicationActivities:nil];
[self presentViewController:activityView animated:YES completion:nil];

Really wish there was more on this, but here it is.

Ben Kreeger
  • 6,355
  • 2
  • 38
  • 53
  • 3
    Note that a single UIActivityItemSource can only return a placeholder for a single piece of data (no returning NSArrays for `activityViewControllerPlaceHolderItem:`. For more info see this question: http://stackoverflow.com/questions/13029340/uiactivityitemsource-protocole-set-complex-object – Doug Dec 10 '12 at 04:20
  • Thanks for the pointer to that other question. I've more-or-less forsaken `UIActivityViewController` for now (I've wasted too many hours getting it to do what I want), since it's so inflexible, but that subclass mentioned in your link seems like a definite step in the right direction. – Ben Kreeger Dec 10 '12 at 14:20
  • I've been struggling with this same problem. It seems odd that they didn't define constants for possible data types so we could key against those. UIActivityViewController is a great idea, but the implementation is a bit wack right now. – poetmountain Dec 17 '12 at 20:51
  • @BenKreeger, I really wish it didn't work this way because I cannot comprehend how Apple thinks this makes any sense. Thanks for your answer because under no circumstances would I have thought of doing it this way. – rob5408 Jul 22 '14 at 14:04
  • @rob5408 Haha don't mention it. I think things have improved for the better in the latest handful of releases, especially iOS 8, but originally the docs were sparse and the API was confusing. – Ben Kreeger Jul 22 '14 at 14:06
  • I ended up with a similar technique to support printing and email. Self handles the email, implementing the UIActivityItemSource as you did. The printing is handled with a UIActivityItemProvider subclass, whose item property is a UIWebView's viewPrintFormatter. The final object in the array is a UIPrintInfo object, providing the jobName and orientation (UIPrintInfoOrientationLandscape). We all deserve a pat on the back for the various aspects of this that we deduced! – Carl Smith Mar 18 '15 at 00:22