UIActivityViewController - 邮件和Twitter分享

35

我最近开始使用UIActivity来分享我的应用程序,但是我遇到了一些问题。首先,我没有找到如何设置电子邮件的主题。有什么办法吗?其次,当我设置电子邮件的正文文本时,会有一个额外的“换行符”(电子邮件的第一行为空白,我的文本从第二行开始)。这是代码:

 NSMutableArray *array = [[NSMutableArray alloc] initWithObjects: @"Test", nil];

    UIActivityViewController *activityViewController = [[UIActivityViewController alloc]
                                   initWithActivityItems:array applicationActivities:nil];

在电子邮件中,它显示为:

"

测试 "

第三个问题:是否有一种方法可以知道用户选择了哪种分享方法?因为我想在用户在Twitter上分享时在我的帖子中包含一个hashtag,但现在它也被整合到电子邮件中,这显然是没有意义的。

谢谢!

5个回答

50

如果在iOS6上使用UIActivityViewController添加电子邮件的主题,这是任何人都可以使用的最佳解决方案。您只需要在初始化UIActivityViewController时调用以下内容即可。

UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:applicationActivities];
[activityViewController setValue:@"My Subject Text" forKey:@"subject"];

您的 UIActivityViewController 已经填充了一个主题。


1
有没有其他的键可以传递到UIActivityViewController中? - vedrano
9
这合法吗?它没有记录。 - Srđan Rašić
1
@Ajay,是否可以根据类似这个键的设置为Twitter和Facebook设置值?例如,如果是Twitter,则使用带有标签和提及的短文本,但如果是FB,则使用较长的版本? - Maziyar
@Maziyar 我没有尝试过类似的事情,但我猜只要这些类定义了那些变量,那应该可以工作。 - Ajay
2
如果你决定使用它,请先检查是否在 iOS 6 上运行。如果不是,则使用新的 UIActivityItemSource 协议方法设置主题。 - fbernardo
显示剩余2条评论

24

在iOS7中,可以通过使用 -

activityViewController:subjectForActivityType:

当发布一个项目时,服务可能会提供一个单独的主题字段和数据字段,例如电子邮件消息。如果您希望为支持主题字段的服务提供主题字段,请实现此方法。
参考链接 - https://developer.apple.com/library/ios/documentation/uikit/reference/UIActivityItemSource_protocol/Reference/Reference.html#//apple_ref/occ/intfm/UIActivityItemSource/activityViewController:subjectForActivityType

16

1和2: 如何在iOS 6中为UIActivityViewController设置收件人?

虽然这两种提供的方法有点像hack,特别是第一种,但是确实是可行的。

3:可以在不同的服务上共享不同的内容,但是项目的数量和类型应该相同(但这并不是限制,因为您可以针对特定服务将项目设为nil)。使用UIActivityItemSource协议在选择了服务后创建共享项目。

我使用的代码:

使用当前控制器作为提供所有项的提供程序显示UIActivityViewController(它应该在.h文件中具有):

const int numberOfSharedItems = 5;

- (IBAction)shareAction:(id)sender
{
    NSMutableArray *shareItems = [NSMutableArray new];
        while ([shareItems count] < numberOfSharedItems)
            [shareItems addObject: self];

        UIActivityViewController *shareController =
            [[UIActivityViewController alloc]
                // actual items are prepared by UIActivityItemSource protocol methods below
                initWithActivityItems: shareItems
                applicationActivities :nil];

        shareController.excludedActivityTypes = @[UIActivityTypeMessage, UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll];

        [self presentViewController: shareController animated: YES completion: nil];
}
制作共享项目的占位符:
-(id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController
{
    static UIActivityViewController *shareController;
    static int itemNo;
    if (shareController == activityViewController && itemNo < numberOfSharedItems - 1)
        itemNo++;
    else {
        itemNo = 0;
        shareController = activityViewController;
    }

    switch (itemNo) {
        case 0: return @""; // intro in email
        case 1: return @""; // email text
        case 2: return [NSURL new]; // link
        case 3: return [UIImage new]; // picture
        case 4: return @""; // extra text (via in twitter, signature in email)
        default: return nil;
    }
}
制作实际的项目,为不同的服务分别制作:
-(id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
{
    // the number of item to share
    static UIActivityViewController *shareController;
    static int itemNo;
    if (shareController == activityViewController && itemNo < numberOfSharedItems - 1)
        itemNo++;
    else {
        itemNo = 0;
        shareController = activityViewController;
    }

    NSString *shareText = [self shareText]; // whatever you fancy
    NSURL *shareURL = [self shareURL];

    // twitter
    if ([activityType isEqualToString: UIActivityTypePostToTwitter])
        switch (itemNo) {
            case 0: return nil;
            case 1: return shareText; // you can change text for twitter, I add $ to stock symbol inside shareText here, e.g. Hashtags can be added too
            case 2: return shareURL;
            case 3: return nil; // no picture
            case 4: return @"via @YourApp";
            default: return nil;
        }

    // email
    else if ([activityType isEqualToString: UIActivityTypeMail])
        switch (itemNo) {
            case 0: return @"Hi!\r\n\r\nI used YourApp\r\n";
            case 1: return shareText;
            case 2: return shareURL;
            case 3: return nil; // no picture
            case 4: return [@"\r\nCheck it out.\r\n\r\nCheers\r\n" stringByAppendingString: [self userName]];
            default: return nil;
        }

    else // Facebook or something else in the future
        switch (itemNo) {
            case 0: return nil;
            case 1: return shareText;
            case 2: return shareURL;
            case 3: return [self shareImage];
            case 4: return nil;
            default: return nil;
        }
}

4
这个答案很好地展示了 UIActivityItemSource 协议的工作原理以及如何用于不同类型的活动,但我不建议直接使用它——它对 itemNo 的依赖和这些方法被内部的 UIActivityViewController 代码调用的顺序是固化的... 这可能会在下游改变调用方式时导致一些问题。 - natbro
你能澄清一下你是如何使用它的吗?我想在Facebook上包含一个图像/文本/URL等。我可以只使用MYNActivityProvider *provider0 = [[MYNActivityProvider alloc]init]; UIActivityViewController *vc = [[UIActivityViewController alloc] initWithActivityItems:@[provider0] applicationActivities:nil]; 吗?当我尝试这样做时,它只返回第一个文本项/没有图像供Facebook/Twitter使用。 - johndpope
@johndpope 抱歉,已经过了一段时间...看起来你可能有比我当时使用的更新的API。 - esp
@esp你的回答是我迄今为止在这个主题上找到的最好的文档!只是顺便说一句,在FB中,如果我返回URL,我会得到额外的itemForActivityType调用,它可以正常工作。 - Nir Golan

2

你可以按照以下方式创建一个类:

 @interface MYNActivityProvider : UIActivityItemProvider <UIActivityItemSource>

 @end

// 实现

 - (id) activityViewController:(UIActivityViewController *)activityViewController
      itemForActivityType:(NSString *)activityType
 { 
    if ( [activityType isEqualToString:UIActivityTypePostToTwitter] ) {
        return stringToPost;
     }
    if ( [activityType isEqualToString:UIActivityTypePostToFacebook] ) {
         return stringToPost;
    }
    if ( [activityType isEqualToString:UIActivityTypeMessage] ) {
        return @"SMS message text";  
    }
    if ( [activityType isEqualToString:UIActivityTypeMail] ) {
        return @"Email text here!";
    }
    if ( [activityType isEqualToString:@"Custom"] ) {
        return @"app custom text";
    }
    return nil;
 }

0

你可能想要尝试 OvershareKit

我们经常被问到为什么有人会使用 OvershareKit 而不是 UIActivityViewController (UIAVC) 和 UIActivity。UIAVC 对于那些知道他们永远不需要以下任何一个功能的应用程序非常方便:

  1. 永远不需要与一个或两个第三方服务集成。
  2. 永远不需要调整活动表和共享屏幕的用户界面。
  3. 不关心为每种共享类型提供单独的媒体特定内容(电子邮件与短信等)
  4. 永远不需要在同一张表中有多个项目,例如复制文本与复制链接。
  5. 不介意所有非系统提供的活动都带有沉闷的单色图标。

您的情况是(3) - 需要关心不同共享类型的不同内容。


1
值得一提的是,它只适用于iOS 7。 - Maciej Swic
这个项目已经不再进行活跃开发,并且无法在9+版本上构建。 - mKane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接