However, there are many occasions where you probably want to do things differently depending on the service. For example, you may want to send a particular message when posting to Facebook and a different one when posting to Twitter. The character limit on Twitter may mean, for example, that you want to truncate the message that you post to Twitter. You may want to have a different image resolution for different things.
How do you do this? This post describes one approach to achieve this - using the UIActivityItemProvider class.
This class uses the call back defined in the UIActivityItemSource protocol to enable you to vary the data depending on activity type.
Step 1: Start with the Previous Example
This example builds upon the example in the previous post.
Step 2: Creates a Subclass of the UIActivityItemProvider Class
Add the following code to the ViewController.m file:
@interface TextItemProvider:UIActivityItemProvider
@property (nonatomic, strong) NSString *someText;
@end
@implementation TextItemProvider
@synthesize someText = _someText;
- (id)initWithPlaceholderItem:(id)placeholderItem
{
//Initializes and returns a provider object with the specified placeholder data
return [super initWithPlaceholderItem:placeholderItem];
}
- (id)item
{
//Generates and returns the actual data object
return @"";
}
// The following are two methods in the UIActivityItemSource Protocol
// (UIActivityItemProvider conforms to this protocol) - both methods required
//- Returns the data object to be acted upon. (required)
- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
{
if ([activityType isEqualToString:UIActivityTypePostToFacebook]) {
NSString *theText = @"Some text for Facebook";
return theText;
}
if ([activityType isEqualToString:UIActivityTypePostToTwitter]) {
NSString *theText = @"Some text for Twitter";
return theText;
}
if ([activityType isEqualToString:UIActivityTypePostToWeibo]) {
NSString *theText = @"Some text for Weibo";
return theText;
}
if ([activityType isEqualToString:UIActivityTypeMail]) {
NSString *theText = _someText;
return theText;
}
if ([activityType isEqualToString:kYourCustomMailType]) {
NSString *theText = @"Some text for your Custom Type";
return theText;
}
return @"Some default text";
}
//- Returns the placeholder object for the data. (required)
//- The class of this object must match the class of the object you return from the above method
- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController
{
return @"";
}
@end
The above creates a class called TextItemProvider, which is a subclass of the UIActivityItemProvider. For convenience here, the code is put in the ViewController.m file. You may want to put this in a separate file and #import it.
The comments inserted into the code above should provide a good idea of how it works.
Essentially, object of this class serves as a proxy for the eventual data/ object that get passed to the Activity View Controller. According to the documentation it is a type of operation (NSOperation) that enables you to delay passing data. As it runs asynchronously (i.e. not in the main thread) it can be used to process large data (e.g. video files) without disrupting the user experience.
The most important method to achieve our goal here is the method:
(id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
This method is defined in the UIActivityItemSource protocol (the UIActivityItemProvider class conforms to this protocol). When the user clicks the service in the activity view controller screen, this method is called and it returns the data object, which is a NSString object in this case (but it can be other objects). In this example, the codes simply generate a different text depending on the activityType.
Step 3: Create the UIActivityItemProvider object and add it to the Activity View Controller
Delete the line in the previous example that says:
NSArray *activityItems = [NSArray arrayWithObjects:textObject, url, image, nil];
(You can also delete the NSString, NSURL, UIImage lines above it too if you like, but leaving it should not harm this example.)
And replace it with the following:
TextItemProvider *textItem = [[TextItemProvider alloc] initWithPlaceholderItem:@"Default text"];
textItem.someText = _aTextView.text;
NSArray *activityItems = [NSArray arrayWithObjects:textItem, nil];
This creates a TextItemProvider object called textItem. The next line simply passes the text in aTextView to the textItem object so that it can use the text (if required) when it generates the NSString data. You can pass other data or variables to it if required by your app.
When the activity view controller is instantiated (see previous code), the textItem object will be one of the Activity Item.
The result is that when you clicked the Twitter icon in the Activity View screen, the Twitter screen will contain the text "Some text for Twitter". If you click the Facebook icon, it will be "Some text for Facebook", and so on.