ios - usar - ¿Cómo uso UIActivityItemProvider para enviar un correo electrónico con datos adjuntos con UIActivityViewController?
¿cómo recibir un mail drop (2)
Estoy tratando de usar UIActivityItemProvider para compartir un archivo desde mi aplicación a través de un archivo adjunto de correo electrónico. También necesito rellenar el asunto del correo electrónico y especificar que el nombre del archivo adjunto sea diferente al nombre del archivo almacenado en el dispositivo.
Aquí está el código que estoy usando. El problema es que el archivo adjunto falta en el correo electrónico.
@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
Y luego en mi viewController hago esto:
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];
Estoy enviando un correo electrónico con archivo adjunto sin ItemProvider. esta funcionando bien :-)
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];
Para aquellos que aún se encuentran con una solución para esto, hay una solución más elegante para personalizar UIActivityViewController
. Para abordar la pregunta original, la razón por la que no se muestra el archivo adjunto es porque se supone que es un objeto UIActivityItemProvider
separado.
Entonces, la solución es crear dos subclases UIActivityItemProvider
, una para envolver el ''emailBody'' y ''emailSubject'' y otra para envolver el adjunto. La ventaja de utilizar un UIActivityItemProvider
para el archivo adjunto es que tiene la oportunidad de retrasar el procesamiento del archivo adjunto hasta que sea necesario, en lugar de hacerlo antes de presentar UIActivityViewController
.
Implemente la clase AttachmentProvider
para proporcionar el adjunto de esta manera:
@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
Implemente la clase EmailInfoProvider
para proporcionar el cuerpo del correo electrónico y la clase del sujeto de esta manera:
@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
Luego, puede crear un UIActivityViewController
con estos dos elementos en su viewController como:
- (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];
}