我如何使用UIActivityItemProvider发送带有UIActivityViewController附件的电子邮件?

我想通过电子邮件附件使用UIActivityItemProvider从我的应用程序共享文件。 我还需要填写电子邮件的主题行,并指定附件的名称与设备上存储的文件的名称不同。

这是我正在使用的代码。 问题是电子邮件中缺less附件。

@interface ItemProvider:UIActivityItemProvider @property (nonatomic, strong) NSURL *filepath; @property (nonatomic, strong) NSString *emailBody; @property (nonatomic, strong) NSString *emailSubject; @end @implementation ItemProvider - (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 [NSDictionary dictionary]; } // The following are two methods in the UIActivityItemSource Protocol // (UIActivityItemProvider conforms to this protocol) - both methods required #pragma mark UIActivityItemSource //- Returns the data object to be acted upon. (required) - (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType { if ([activityType isEqualToString:UIActivityTypeMail]) { return @{@"body":self.emailBody, @"url":self.filepath}; } return @{@"body":self.emailBody, @"url":self.filepath}; } //- 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 @{@"body":self.emailBody, @"url":self.filepath}; } -(NSString *) activityViewController:(UIActivityViewController *)activityViewController subjectForActivityType:(NSString *)activityType { return self.emailSubject; } @end 

然后在我的viewController我这样做:

  ItemProvider *provider = [[ItemProvider alloc] initWithPlaceholderItem:@{@"body":emailBody, @"url":filePath}]; provider.emailBody = emailBody; provider.emailSubject = info.title; provider.filepath = filePath; NSArray *activityItems = @[provider]; // Build a collection of custom activities (if you have any) // NSMutableArray *customActivities = [[NSMutableArray alloc] init]; UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil]; [self presentViewController:activityController animated:YES completion:nil]; 

我发送没有ItemProvider附件的电子邮件。 它的工作很好:-)

 NSMutableArray *selDocs = [[NSMutableArray alloc] init]; for (Document *theDoc in self.selectedDocs) { NSURL *fileUrl = [NSURL fileURLWithPath:theDoc.filePath]; [selDocs addObject:fileUrl]; } NSArray *postItems = [NSArray arrayWithArray:selDocs]; UIActivityViewController *avc = [[UIActivityViewController alloc] initWithActivityItems:postItems applicationActivities:nil]; [avc setValue:@"Your email Subject" forKey:@"subject"]; avc.completionHandler = ^(NSString *activityType, BOOL completed){ NSLog(@"Activity Type selected: %@", activityType); if (completed) { NSLog(@"Selected activity was performed."); } else { if (activityType == NULL) { NSLog(@"User dismissed the view controller without making a selection."); } else { NSLog(@"Activity was not performed."); } } }; [self presentViewController:avc animated:YES completion:nil]; 

对于那些仍然陷入这个问题的解决scheme,有一个更优雅的解决scheme来定制UIActivityViewController 。 为了解决原来的问题,附件没有显示的原因是因为它应该是一个单独的UIActivityItemProvider对象。

所以解决方法是创build两个UIActivityItemProvider子类,一个包装“emailBody”和“emailSubject”,另一个包装附件。 为附件使用UIActivityItemProvider的好处是,您有机会延迟处理附件直到需要,而不是在呈现UIActivityViewController之前这样做。

实现AttachmentProvider类来提供附件,如下所示:

 @implementation AttachmentProvider : UIActivityItemProvider - (id)item { if ([self.activityType isEqualToString:UIActivityTypeMail]) { /* Replace with actual URL to a file. Alternatively * you can also return a UIImage. */ return [NSData dataWithContentsOfURL:dataURL]; } return nil; } @end 

实现EmailInfoProvider类来提供电子邮件正文和主题类,如下所示:

 @implementation EmailInfoProvider : UIActivityItemProvider - (id)item { return @"Your email body goes here"; } - (NSString *)activityViewController:(UIActivityViewController *)activityViewController subjectForActivityType:(NSString *)activityType { if ([activityType isEqualToString:UIActivityTypeMail]) { return @"Your subject goes here"; } return nil; } @end 

你可以在你的viewController中创build一个UIActivityViewController ,它们都是这样的:

 - (void)shareAction { AttachmentProvider *attachment = [[AttachmentProvider alloc] init]; EmailInfoProvider *emailContent = [[EmailInfoProvider alloc] init]; // You can provider custom -(id)init methods to populate EmailInfoProvider UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:@[attachment, emailContent] applicationActivities:nil]; [self presentViewController:activityController animated:YES completion:nil]; }