ios 如何使用 UIActivityItemProvider 发送带有 UIActivityViewController 附件的电子邮件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20581389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I use UIActivityItemProvider to send an email with attachment with UIActivityViewController?
提问by RawMean
I am trying to use UIActivityItemProvider to share a file from within my app via email attachment. I also need to populate the subject line of the email and to specify the name of the attachment to be something different than the name of the file stored on the device.
我正在尝试使用 UIActivityItemProvider 通过电子邮件附件从我的应用程序中共享文件。我还需要填充电子邮件的主题行,并将附件名称指定为与设备上存储的文件名称不同的名称。
Here is the code that I'm using. The problem is that the attachment is missing from the email.
这是我正在使用的代码。问题是电子邮件中缺少附件。
@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
And then in my viewController I do this:
然后在我的 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];
采纳答案by thorb65
i'm sending email with attachment without ItemProvider. its working well :-)
我正在发送没有 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];
回答by dbart
For those still stumbling upon a solution for this, there is a more elegant solution for customizing UIActivityViewController
. To address the original question, the reason the attachment is not showing up is because it is supposed to be a separate UIActivityItemProvider
object.
对于那些仍然在寻找解决方案的人来说,有一个更优雅的定制UIActivityViewController
. 为了解决最初的问题,附件没有出现的原因是因为它应该是一个单独的UIActivityItemProvider
对象。
So the solution is to create two UIActivityItemProvider
subclasses, one to wrap the 'emailBody' and 'emailSubject' and another to wrap the attachment. The benefit to using a UIActivityItemProvider
for the attachment is that you have the opportunity to delay processing the attachment until it is needed, rather than doing so before presenting UIActivityViewController
.
因此,解决方案是创建两个UIActivityItemProvider
子类,一个用于包装“emailBody”和“emailSubject”,另一个用于包装附件。UIActivityItemProvider
对附件使用 a 的好处是您有机会延迟处理附件,直到需要它,而不是在呈现之前这样做UIActivityViewController
。
Implement the AttachmentProvider
class to provide the attachment like so:
实现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
Implement EmailInfoProvider
class to provider the email body and subject class like so:
实现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
You can then create a UIActivityViewController
with both these items in your viewController like so:
然后,您可以UIActivityViewController
在 viewController 中使用这两个项目创建一个,如下所示:
- (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];
}