如何设置UIActivityViewController收件人的iOS 6?(How do I se

2019-06-18 08:14发布

我使用的是新UIActivityViewController类iOS6的为用户提供各种共享选项的用户。 你可以传递参数给它,如文本,链接和图像数组并没有休息。

如何定义收件人? 例如通过邮件或短信分享应该能够接受的接受者,而是我无法弄清楚如何调用该行为。

我不希望有需要使用MFMessageComposeViewControllerUIActivityViewController分别为刚刚击败共享控制器的目的。

有什么建议?

UIActivityViewController类参考

编辑:这现在已经提交苹果公司,随后与重复的bug报告合并。

在OpenRadar bug报告

Answer 1:

这里一切归功于艾曼纽尔,因为他想出了大部分的代码。

虽然我想我会发布他的代码修改后的版本是帮助设置到收件人。

我用MFMailComposeViewController类别

#import "MFMailComposeViewController+Recipient.h"
#import <objc/message.h>

@implementation MFMailComposeViewController (Recipient)

+ (void)load {
    MethodSwizzle(self, @selector(setMessageBody:isHTML:), @selector(setMessageBodySwizzled:isHTML:));
}



static void MethodSwizzle(Class c, SEL origSEL, SEL overrideSEL)
{
    Method origMethod = class_getInstanceMethod(c, origSEL);
    Method overrideMethod = class_getInstanceMethod(c, overrideSEL);

    if (class_addMethod(c, origSEL, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
        class_replaceMethod(c, overrideSEL, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
    } else {
        method_exchangeImplementations(origMethod, overrideMethod);
    }
}

- (void)setMessageBodySwizzled:(NSString*)body isHTML:(BOOL)isHTML
{
    if (isHTML == YES) {
        NSRange range = [body rangeOfString:@"<torecipients>.*</torecipients>" options:NSRegularExpressionSearch|NSCaseInsensitiveSearch];
        if (range.location != NSNotFound) {
            NSScanner *scanner = [NSScanner scannerWithString:body];
            [scanner setScanLocation:range.location+14];
            NSString *recipientsString = [NSString string];
            if ([scanner scanUpToString:@"</torecipients>" intoString:&recipientsString] == YES) {
                NSArray * recipients = [recipientsString componentsSeparatedByString:@";"];
                [self setToRecipients:recipients];
            }
            body = [body stringByReplacingCharactersInRange:range withString:@""];
        }
    }
    [self setMessageBodySwizzled:body isHTML:isHTML];
}

@end


Answer 2:

对于添加对象到iOS6的使用UIActivityViewController的电子邮件,这是任何人都可以使用。所有你需要做的就是调用下面在初始化UIActivityViewController的最佳解决方案。

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

而你UIActivityViewController填充了一个主题。



Answer 3:

我只是想出了一个解决这个问题(在我的情况设置电子邮件的主题):作为内部的UIActivityViewController将调用在某些时候setMessageBody:isHTML:方法MFMailComposeViewController类的,只是截取该呼叫和内部进行打电话到SETSUBJECT:方法。 感谢“方法混写”美特殊,它看起来像:

#import <objc/message.h>

static void MethodSwizzle(Class c, SEL origSEL, SEL overrideSEL)
{
    Method origMethod = class_getInstanceMethod(c, origSEL);
    Method overrideMethod = class_getInstanceMethod(c, overrideSEL);

    if (class_addMethod(c, origSEL, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
        class_replaceMethod(c, overrideSEL, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
    } else {
        method_exchangeImplementations(origMethod, overrideMethod);
    }
}

@implementation MFMailComposeViewController (force_subject)

- (void)setMessageBodySwizzled:(NSString*)body isHTML:(BOOL)isHTML
{
    if (isHTML == YES) {
        NSRange range = [body rangeOfString:@"<title>.*</title>" options:NSRegularExpressionSearch|NSCaseInsensitiveSearch];
        if (range.location != NSNotFound) {
            NSScanner *scanner = [NSScanner scannerWithString:body];
            [scanner setScanLocation:range.location+7];
            NSString *subject = [NSString string];
            if ([scanner scanUpToString:@"</title>" intoString:&subject] == YES) {
                [self setSubject:subject];
            }
        }
    }
    [self setMessageBodySwizzled:body isHTML:isHTML];
}

@end

使用UIActivityViewController之前调用下面的代码行:

MethodSwizzle([MFMailComposeViewController class], @selector(setMessageBody:isHTML:), @selector(setMessageBodySwizzled:isHTML:));

然后传递给UIActivityViewController定制UIActivityItemProvider对于UIActivityTypeMail返回一个HTML的NSString像:

<html><head>
<title>Subject of the mail</title>
</head><body>
Body of the <b>mail</b>
</body></html>

该电子邮件的主题是从HTML标题中提取(使用纯文本的那部分,没有HTML实体或标签)。

使用这种方法,我让你阐述一种优雅的方式来设置邮件收件人。



Answer 4:

虽然它出现,目前的mailto:设置邮件主题和正文不工作,这在任何情况下是不够的,如果你想设置电子邮件正文中包含HTML,仍然使用苹果的系统邮件图标的解决方案通过UIActivityViewController。

这正是我们想要做的:使用系统图标,但有电子邮件包含HTML体和自定义主题。

我们的解决方案是一个平庸的东西,但它工作得很好,至少在那一刻。 它不涉及使用MFMailComposeViewController,但它仍然可以让您使用UIActivityViewController系统邮件图标。

第1步:创建一个包装类符合UIActivityItemSource像这样:

    @interface ActivityItemSource : NSObject <UIActivityItemSource>
    @property (nonatomic, strong) id object;
    - (id) initWithObject:(id) objectToUse;
    @end

    @implementation ActivityItemSource

   - (id) initWithObject:(id) objectToUse
    {
        self = [super init];
        if (self) {
            self.object = objectToUse;
        }
        return self;
    }


    - (id)activityViewController:(UIActivityViewController *)activityViewController                 itemForActivityType:(NSString *)activityType
    {
    return self.object;
    }

    - (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController
    {

        return self.object;
    }

第2步:子类UIActivityViewController并使其成为一个MFMailComposeViewControllerDelegate像这样:

    @interface ActivityViewController : UIActivityViewController         <MFMailComposeViewControllerDelegate>

    @property (nonatomic, strong) id object;

    - (id) initWithObject:(id) objectToUse;
    @end


    @implementation ActivityViewController

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

        switch (result)
        {
            case MFMailComposeResultSent:
            case MFMailComposeResultSaved:
                //successfully composed an email
                break;
            case MFMailComposeResultCancelled:
                break;
            case MFMailComposeResultFailed:
                break;
        }

    //dismiss the compose view and then the action view
        [self dismissViewControllerAnimated:YES completion:^() {
            [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];        
        }];

    }

    - (id) initWithObject:(id) objectToUse
    {

        self = [super initWithActivityItems:[NSArray arrayWithObjects:[[ActivityItemSource alloc] initWithObject:objectToUse], nil] applicationActivities:nil];

        if (self) {
            self.excludedActivityTypes = [NSArray arrayWithObjects: UIActivityTypePostToWeibo, UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, nil];

            self.object = objectToUse;
        }
        return self;
    }

注:当你调用super initWithActivityItems你包装,你会在您的自定义ActivityItemSource可以共享该对象

第3步:推出自己的MFMailComposeViewController代替系统之一,当用户点击邮件图标。

你可以这样做在activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType在ActivityItemSource类方法:

    - (id)activityViewController:(UIActivityViewController *)activityViewController                 itemForActivityType:(NSString *)activityType
    {
        if([activityType isEqualToString:UIActivityTypeMail]) {
                //TODO: fix; this is a hack; but we have to wait till apple fixes the         inability to set subject and html body of email when using UIActivityViewController
                [self setEmailContent:activityViewController];
                return nil;
            }
         return self.object;
    }


    - (void) setEmailContent:(UIActivityViewController *)activityViewController 
    {

       MFMailComposeViewController *mailController = [ShareViewController mailComposeControllerWithObject: self.object withDelegate: activityViewController];

        [activityViewController presentViewController:mailController animated:YES completion:nil];

    }

mailComposeControllerWithObject方法实例化MFMailComposeViewController类的一个实例,并将它设置为包含任何你想要的数据。 还需要注意的是,你将设置activityViewController为撰写视图的委托。

这部作品的原因是显示撰写模式时,它可以防止显示的其他情态动词,即你展示自己撰写视图块被所示的系统撰写视图。 这绝对是一个黑客,但它能够完成任务。

希望这可以帮助。



Answer 5:

你应该能够包括使用NSURL对象和邮寄地址收件人:方案(或短信:文本消息)。

从UIActivity类的引用:

UIActivityTypeMail对象的帖子所提供的内容,新的电子邮件。 当使用该服务,您可以提供的NSString和UIImage的对象和NSURL对象指向本地文件作为活动项目的数据。 你也可以指定NSURL对象,其内容使用mailto模式。

因此,这样的事情应该工作:

NSString *text = @"My mail text";
NSURL *recipients = [NSURL URLWithString:@"mailto:foo@bar.com"];

NSArray *activityItems = @[text, recipients];

UIActivityViewController *activityController =
                    [[UIActivityViewController alloc]
                    initWithActivityItems:activityItems
                    applicationActivities:nil];

[self presentViewController:activityController
                   animated:YES completion:nil];


Answer 6:

我不知道有关收件人,但它好像在iOS的7,以后你可以通过符合设定的电子邮件的主题UIActivityItemSource协议和实施方法activityViewController:subjectForActivityType:



文章来源: How do I set recipients for UIActivityViewController in iOS 6?