在 Xcode 中使用 UIActivityViewController 填写电子邮件标题(和附件)

Posted

技术标签:

【中文标题】在 Xcode 中使用 UIActivityViewController 填写电子邮件标题(和附件)【英文标题】:Filling in email header (and attaching file) using UIActivityViewController in Xcode 【发布时间】:2015-07-01 02:40:42 【问题描述】:

第一篇文章,所以我会尽量直接和详细...我正在使用 UIActivityViewController 和子类化UIActivityItemProvider 根据选择的共享方法以不同的方式处理共享文本(这个线程帮助了批号:How to know which icon is clicked in UIActivityViewController before activityController setCompletionHandleris called?)。

我想我已经弄清楚了将源数据传入然后根据所选 itemForActivityType 进行处理的机制,但是对于电子邮件共享,我还想预先填充标题(主题、正文等)作为附件。我知道如何使用独立的MFMailComposeViewController 执行此操作,但我不太了解如何使用ActivityViewController 执行此操作。在这里:UIActivityViewController - Email and Twitter sharing,有人提到在初始化程序上使用值/键对,例如:

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

但是设置收件人和消息正文的其他标准键是什么?

附加文件是我遇到的另一个大问题。我知道如何创建文档并将其保存在文件系统上并附加它 - 再次使用 MFMailComposeViewController - 但我想使用 UIActivityViewController 获得相同的行为。

(对不起,冗长...)

【问题讨论】:

【参考方案1】:

设置你应该使用的主题 - (NSString *)activityViewController:(UIActivityViewController *)activityViewController subjectForActivityType:(NSString *)activityType

对于您的数据(文本和图像),您可以通过activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType 传递它们,这将为您的数据返回一个 UTI,以便服务可以更好地处理数据。您使用的密钥并不重要,因为 UTI 将有助于识别项目。苹果文档:

提供 UTI 允许服务以适当的方式处理特定数据类型,例如电子邮件服务格式化图像以在线显示。 More info here

【讨论】:

好的,如果 UIActivityType 是邮件消息,该方法也可以用于添加附件吗? 是的,ios 有一个用于图像的 UTI,因此它会识别作为数据传入的图像并附加它。好吧,实际上它会在电子邮件的情况下内联添加它。 我想我的意思是添加任何类型的附件的一般情况。具体来说,我正在使用视图控制器上各个字段的数据创建一个 .TXT 文档,并且我想将文本文件附加到邮件消息中。 .txt 文件应该可以正常工作,因为它是 iOS 中定义的标准 UTI 类型之一。邮件应用程序应能识别并附加它。【参考方案2】:

我认为如果不创建自己的 UIActivity 子类 (YourActivity) 就不能直接访问邮件控制器。

在“YourActivity”中设置您的 MFMailComposeViewController,它将像在您的主代码中一样运行。这是我的做法:

在 YourActivity.h 中:

让自己成为邮件控制器的委托,并为邮件视图控制器和选定的视图控制器设置方法范围的变量:

@interface YourActivity : UIActivity <MFMailComposeViewControllerDelegate>

    MFMailComposeViewController *mailController;
    UIViewController *activityViewController;

在 YourActivity.m 中:

(可选)我建议您尽早检查邮件服务的可用性。 (这将防止向用户提供无法完成的选项):

- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems

    // If mail is unavailable, can't perform activity
    if (![MFMailComposeViewController canSendMail]) 
        return NO;
    

    for (id item in activityItems) 
        // whatever other checks you want to do
        return YES;
    
    return NO;

在 YourActivity -prepareWithActivityItems: 方法中设置您的 MFMailComposeViewController:

- (void)prepareWithActivityItems:(NSArray *)activityItems

    // See if we can send mail (shouldn't happen if we checked already in -canPerformActivityWithItems)
    if (![MFMailComposeViewController canSendMail]) 

        UIAlertController *mailAlertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Mail Unavailable", @"mail unavailable")
                                                                                     message:nil
                                                                              preferredStyle:UIAlertControllerStyleAlert];

        UIAlertAction *cancel = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", @"cancel")
                                                         style:UIAlertActionStyleCancel
                                                       handler:^(UIAlertAction * _Nonnull action) 
                                                           [self activityDidFinish:NO];
                                                       ];

        [mailAlertController addAction:cancel];

        // Set the alert as the view to return
        activityViewController = mailAlertController;
    

    // Create a mail view controller
    mailController = [[MFMailComposeViewController alloc] init];

    // Set Delegate
    [mailController setMailComposeDelegate:self];

    // Set mail controller as the view to return
    activityViewController = mailController;

    // Paste the rest of your MFMailComposeViewController code here

在 YourActivity -activityViewController 方法中返回您选择的视图控制器:

- (UIViewController *)activityViewController

    return activityViewController;

记得实现邮件完成处理程序,至少要关闭作曲家视图:

- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error

    // Send any messages, if desired, to the controller before dismissing
    NSString *message = nil;
    NSString *errorMessage = nil;

    if (result == MFMailComposeResultFailed) 
        message = NSLocalizedString(@"Unable to send email", @"Unable to send email");
    

    if (error) 
        errorMessage = [message stringByAppendingString:[NSString stringWithFormat:NSLocalizedString(@"Error:\n%@", @"error:\n%@"), [error localizedDescription]]];
    

    // Send mail status alert message, if needed
    if (message) 
        UIAlertController *mailAlert = [UIAlertController alertControllerWithTitle:message
                                                                           message:errorMessage
                                                                    preferredStyle:UIAlertControllerStyleAlert];

        UIAlertAction *cancel = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"OK")
                                                         style:UIAlertActionStyleCancel
                                                       handler:^(UIAlertAction * _Nonnull action) 
                                                           // Dismiss the mail controller
                                                           [controller dismissViewControllerAnimated:true completion:^];

                                                           [controller release];
                                                           mailController = nil;
                                                       ];

        [mailAlert addAction:cancel];

        [controller presentViewController:mailAlert animated:YES completion:^
            //
        ];

    

    else 
        // Dismiss the mail controller
        [controller dismissViewControllerAnimated:true completion:^];

        [controller release];
        mailController = nil;
    

【讨论】:

以上是关于在 Xcode 中使用 UIActivityViewController 填写电子邮件标题(和附件)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Xcode 12.5.1 或 Xcode 13 中使用 OSLog?

Xcode项目使用xcode项目时问题在其他mac上的其他xcode中启动

在设备中使用 xcode 4.5.2 运行 xcode 4.3.3 项目..(模拟器中没有问题)

Xcode 中 Git 的配置与使用

在 Xcode 7.3 中使用 Cocoapods

在 Xcode 6 中使用自定义字体 - Swift [重复]