Si bien parece que en la actualidad el mailto: solución para el establecimiento de asunto del correo electrónico y el cuerpo no está trabajando, esto sería en todo caso no será adecuado si desea establecer el cuerpo del correo electrónico para que contenga HTML y aún hacer uso del icono de correo electrónico del sistema de Apple a través de UIActivityViewController.
Eso es exactamente lo que queríamos hacer: usar el ícono del sistema, pero hacer que el correo electrónico contenga un cuerpo HTML y un asunto personalizado.
Nuestra solución fue algo así como un truco, pero funciona bien, al menos por el momento. Implica el uso de MFMailComposeViewController, pero todavía le permite usar el icono de correo del sistema con UIActivityViewController.
Paso 1: Crear una clase de contenedor conforme a la UIActivityItemSource así:
@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;
}
Paso 2: Subclase UIActivityViewController y convertirlo en un MFMailComposeViewControllerDelegate así:
@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;
}
NOTA: cuando se están llamando al super initWithActivityItems
, estás ajustando el objeto que compartirás en tu ActivityItemSource personalizado
Paso 3: inicie su propio MFMailComposeViewController en lugar del sistema uno cuando un usuario toque el icono de Correo.
Se podría hacer esto en el método activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
en la clase 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];
}
En el mailComposeControllerWithObject
método que se crea una instancia de la clase MFMailComposeViewController y configurarlo para que contenga todos los datos que desea. Tenga en cuenta también que establecería el activityViewController
como el delegado de la vista de composición.
La razón por la que esto funciona es que cuando se muestra un modal de redacción, impide que se muestren otros modales, es decir, que muestre sus propios bloques de vista de composición, no se muestre la vista de composición del sistema. Definitivamente un truco, pero hace el trabajo bien.
Espero que esto ayude.
Solución bastante horrible – Andy
¿Puede compartir el ejemplo completo? – Rajeev
¿Esto ha funcionado para cualquier persona? Si es así, ¿puedes compartir el código completo? – mKane