¿Cómo puedo enviar correo desde una aplicación de iPhone?

242

Quiero enviar un correo electrónico desde la aplicación de mi iPhone. He oído que el SDK de iOS no tiene una API de correo electrónico. No quiero usar el siguiente código porque saldrá de mi aplicación:

NSString *url = [NSString stringWithString: @"mailto:[email protected][email protected]&subject=Greetings%20from%20Cupertino!&body=Wish%20you%20were%20here!"];
[[UIApplication sharedApplication] openURL: [NSURL URLWithString: url]];

Entonces, ¿cómo puedo enviar un correo electrónico desde mi aplicación?

Khushi
fuente

Respuestas:

430

En iOS 3.0 y versiones posteriores, debe usar la MFMailComposeViewControllerclase y el MFMailComposeViewControllerDelegateprotocolo, que está escondido en el marco de MessageUI.

Primero agregue el marco e importe:

#import <MessageUI/MFMailComposeViewController.h>

Luego, para enviar un mensaje:

MFMailComposeViewController* controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:@"My Subject"];
[controller setMessageBody:@"Hello there." isHTML:NO]; 
if (controller) [self presentModalViewController:controller animated:YES];
[controller release];

Luego, el usuario hace el trabajo y obtiene la devolución de llamada delegada a tiempo:

- (void)mailComposeController:(MFMailComposeViewController*)controller  
          didFinishWithResult:(MFMailComposeResult)result 
                        error:(NSError*)error;
{
  if (result == MFMailComposeResultSent) {
    NSLog(@"It's away!");
  }
  [self dismissModalViewControllerAnimated:YES];
}

Recuerde verificar si el dispositivo está configurado para enviar correos electrónicos:

if ([MFMailComposeViewController canSendMail]) {
  // Show the composer
} else {
  // Handle the error
}
PeyloW
fuente
55
+1. Los marcos que necesitan importarse se mencionan aquí ( mobileorchard.com/… ).
Dan Rosenstark
71
Para salvarte el salto, necesitas #importar <MessageUI / MFMailComposeViewController.h>
TomH
22
Sólo tener en cuenta que, dado que esta respuesta fue escrito métodos de UIViewController presentModalViewController:animated:y dismissModalViewControllerAnimated:han sido marcados como obsoletos - en lugar de los métodos de reemplazo basados en bloques presentViewController:animated:completion:y dismissViewControllerAnimated:completion:se debe utilizar.
2
Y no olvide establecer delegado en .h @interface viewController : UIViewController <MFMailComposeViewControllerDelegate>
Nazir
18
Y en IOS 6 [self presentModalViewController:controller animated:YES]; reemplaza con [self presentViewController:controller animated:YES completion:nil]; y [self dismissModalViewControllerAnimated:YES]; reemplaza con [self dismissViewControllerAnimated:YES completion:nil];
Nazir
61

MFMailComposeViewController es el camino a seguir después del lanzamiento del software iPhone OS 3.0. Puedes mirar el código de muestra o el tutorial que escribí .

Mugunth
fuente
2
Impresionante publicación de Mugunth. Así se hace amigo!
Jordania
1
Es realmente asombroso. Gracias. Diseñé una vista especialmente para aceptar el correo electrónico y el asunto del usuario. implementando el mismo código, nuevamente muestra una visión algo similar. ¿Puedo invocar el método de delegado desde mi evento de presionar un botón en la clase de controlador de vista? Gracias por su ayuda, Shibin
smakstr
He descargado el mismo código de muestra pero no está enviando ningún correo. Solo indica que el correo se envió correctamente, pero no se recibió ningún correo. Intenté agregar el marco de MessageUI que parecía de color rojo por defecto, pero aún así la aplicación no envía el correo. Cualquier ayuda en este sentido será muy apreciada. Estoy probando la aplicación en el simulador.
Ravi shankar
No se puede enviar correo electrónico desde el simulador.
malaki1974
20

Algunas cosas que me gustaría agregar aquí:

  1. El uso de la URL mailto no funcionará en el simulador ya que mail.app no ​​está instalado en el simulador. Sin embargo, funciona en el dispositivo.

  2. Hay un límite en la longitud de la URL de mailto. Si la URL tiene más de 4096 caracteres, mail.app no ​​se iniciará.

  3. Hay una nueva clase en OS 3.0 que le permite enviar un correo electrónico sin salir de su aplicación. Vea la clase MFMailComposeViewController.

Jeff Atwood
fuente
13

Si desea enviar un correo electrónico desde su aplicación, el código anterior es la única forma de hacerlo a menos que codifique su propio cliente de correo (SMTP) dentro de su aplicación, o haga que un servidor envíe el correo por usted.

Por ejemplo, podría codificar su aplicación para invocar una URL en su servidor que enviaría el correo por usted. Luego simplemente llama a la URL desde su código.

Tenga en cuenta que con el código anterior no puede adjuntar nada al correo electrónico, que el método del cliente SMTP le permitiría hacer, así como el método del lado del servidor.

Genericrich
fuente
12

El siguiente código se utiliza en mi aplicación para enviar un correo electrónico con un archivo adjunto. Aquí los archivos adjuntos son una imagen. Puede enviar cualquier tipo de archivo. Lo único que debe tener en cuenta es que debe especificar el correcto .

agregue esto a su archivo .h

#import <MessageUI/MFMailComposeViewController.h>

Agregue MessageUI.framework a su archivo de proyecto

NSArray *paths = SSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *getImagePath = [documentsDirectory stringByAppendingPathComponent:@"myGreenCard.png"];



MFMailComposeViewController* controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:@"Green card application"];
[controller setMessageBody:@"Hi , <br/>  This is my new latest designed green card." isHTML:YES]; 
[controller addAttachmentData:[NSData dataWithContentsOfFile:getImagePath] mimeType:@"png" fileName:@"My Green Card"];
if (controller)
    [self presentModalViewController:controller animated:YES];
[controller release];

El método de delegado es como se muestra a continuación

  -(void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error;
{
    if (result == MFMailComposeResultSent) {
        NSLog(@"It's away!");
    }
    [self dismissModalViewControllerAnimated:YES];
}
Kannan Prasad
fuente
11

Este es el código que puede ayudarlo, pero no olvide incluir el mensaje ui framewark e incluir el método de delegados MFMailComposeViewControllerDelegate

-(void)EmailButtonACtion{

        if ([MFMailComposeViewController canSendMail])
        {
            MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
            controller.mailComposeDelegate = self;
            [controller.navigationBar setBackgroundImage:[UIImage imageNamed:@"navigation_bg_iPhone.png"] forBarMetrics:UIBarMetricsDefault];
            controller.navigationBar.tintColor = [UIColor colorWithRed:51.0/255.0 green:51.0/255.0 blue:51.0/255.0 alpha:1.0];
            [controller setSubject:@""];
            [controller setMessageBody:@" " isHTML:YES];
            [controller setToRecipients:[NSArray arrayWithObjects:@"",nil]];
            UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
            UIImage *ui = resultimg.image;
            pasteboard.image = ui;
            NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(ui)];
            [controller addAttachmentData:imageData mimeType:@"image/png" fileName:@" "];
            [self presentViewController:controller animated:YES completion:NULL];
        }
        else{
            UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"alrt" message:nil delegate:self cancelButtonTitle:@"ok" otherButtonTitles: nil] ;
            [alert show];
        }

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

        [MailAlert show];
        switch (result)
        {
            case MFMailComposeResultCancelled:
                MailAlert.message = @"Email Cancelled";
                break;
            case MFMailComposeResultSaved:
                MailAlert.message = @"Email Saved";
                break;
            case MFMailComposeResultSent:
                MailAlert.message = @"Email Sent";
                break;
            case MFMailComposeResultFailed:
                MailAlert.message = @"Email Failed";
                break;
            default:
                MailAlert.message = @"Email Not Sent";
                break;
        }
        [self dismissViewControllerAnimated:YES completion:NULL];
        [MailAlert show];
    }
mandeep
fuente
¡Muchas gracias! Ejemplo muy útil con cuerpo HTML.
Resty
4

Swift 2.2. Adaptado de la respuesta de Esq

import Foundation
import MessageUI

class MailSender: NSObject, MFMailComposeViewControllerDelegate {

    let parentVC: UIViewController

    init(parentVC: UIViewController) {
        self.parentVC = parentVC
        super.init()
    }

    func send(title: String, messageBody: String, toRecipients: [String]) {
        if MFMailComposeViewController.canSendMail() {
            let mc: MFMailComposeViewController = MFMailComposeViewController()
            mc.mailComposeDelegate = self
            mc.setSubject(title)
            mc.setMessageBody(messageBody, isHTML: false)
            mc.setToRecipients(toRecipients)
            parentVC.presentViewController(mc, animated: true, completion: nil)
        } else {
            print("No email account found.")
        }
    }

    func mailComposeController(controller: MFMailComposeViewController,
        didFinishWithResult result: MFMailComposeResult, error: NSError?) {

            switch result.rawValue {
            case MFMailComposeResultCancelled.rawValue: print("Mail Cancelled")
            case MFMailComposeResultSaved.rawValue: print("Mail Saved")
            case MFMailComposeResultSent.rawValue: print("Mail Sent")
            case MFMailComposeResultFailed.rawValue: print("Mail Failed")
            default: break
            }

            parentVC.dismissViewControllerAnimated(false, completion: nil)
    }
}

Codigo del cliente :

var ms: MailSender?

@IBAction func onSendPressed(sender: AnyObject) {
    ms = MailSender(parentVC: self)
    let title = "Title"
    let messageBody = "/programming/310946/how-can-i-send-mail-from-an-iphone-application this question."
    let toRecipents = ["[email protected]"]
    ms?.send(title, messageBody: messageBody, toRecipents: toRecipents)
}
Evdzhan Mustafa
fuente
4

Para enviar un correo electrónico desde la aplicación de iPhone, debe hacer la siguiente lista de tareas.

Paso 1: Importa#import <MessageUI/MessageUI.h> en tu clase de controlador donde deseas enviar un correo electrónico.

Paso 2: agregue el delegado a su controlador como se muestra a continuación

 @interface <yourControllerName> : UIViewController <MFMessageComposeViewControllerDelegate, MFMailComposeViewControllerDelegate>

Paso 3: agregue el siguiente método para enviar correos electrónicos.

 - (void) sendEmail {
 // Check if your app support the email.
 if ([MFMailComposeViewController canSendMail]) {
    // Create an object of mail composer.
    MFMailComposeViewController *mailComposer =      [[MFMailComposeViewController alloc] init];
    // Add delegate to your self.
    mailComposer.mailComposeDelegate = self;
    // Add recipients to mail if you do not want to add default recipient then remove below line.
    [mailComposer setToRecipients:@[<add here your recipient objects>]];
    // Write email subject.
    [mailComposer setSubject:@“<Your Subject Here>”];
    // Set your email body and if body contains HTML then Pass “YES” in isHTML.
    [mailComposer setMessageBody:@“<Your Message Body>” isHTML:NO];
    // Show your mail composer.
    [self presentViewController:mailComposer animated:YES completion:NULL];
 }
 else {
 // Here you can show toast to user about not support to sending email.
}
}

Paso 4: Implemente MFMailComposeViewController Delegate

- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(nullable NSError *)error {
[controller dismissViewControllerAnimated:TRUE completion:nil];


switch (result) {
   case MFMailComposeResultSaved: {
    // Add code on save mail to draft.
    break;
}
case MFMailComposeResultSent: {
    // Add code on sent a mail.
    break;
}
case MFMailComposeResultCancelled: {
    // Add code on cancel a mail.
    break;
}
case MFMailComposeResultFailed: {
    // Add code on failed to send a mail.
    break;
}
default:
    break;
}
}
Patrick R
fuente
¿Esta respuesta proporciona información nueva que no está incluida en una de las respuestas existentes?
Florian Koch
2

Swift 2.0

func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?){
    if let error = error{
        print("Error: \(error)")
    }else{
        //NO Error
        //------------------------------------------------
        var feedbackMsg = ""

        switch result.rawValue {
        case MFMailComposeResultCancelled.rawValue:
            feedbackMsg = "Mail Cancelled"
        case MFMailComposeResultSaved.rawValue:
            feedbackMsg = "Mail Saved"
        case MFMailComposeResultSent.rawValue:
            feedbackMsg = "Mail Sent"
        case MFMailComposeResultFailed.rawValue:
            feedbackMsg = "Mail Failed"
        default:
            feedbackMsg = ""
        }

        print("Mail: \(feedbackMsg)")

        //------------------------------------------------
    }
}
brian.clear
fuente
1

Heres una versión Swift:

import MessageUI

class YourVC: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        if MFMailComposeViewController.canSendMail() {
            var emailTitle = "Vea Software Feedback"
            var messageBody = "Vea Software! :) "
            var toRecipents = ["[email protected]"]
            var mc:MFMailComposeViewController = MFMailComposeViewController()
            mc.mailComposeDelegate = self
            mc.setSubject(emailTitle)
            mc.setMessageBody(messageBody, isHTML: false)
            mc.setToRecipients(toRecipents)
            self.presentViewController(mc, animated: true, completion: nil)
        } else {
            println("No email account found")
        }
    }
}

extension YourVC: MFMailComposeViewControllerDelegate {
    func mailComposeController(controller: MFMailComposeViewController!, didFinishWithResult result: MFMailComposeResult, error: NSError!) {
        switch result.value {
        case MFMailComposeResultCancelled.value:
            println("Mail Cancelled")
        case MFMailComposeResultSaved.value:
            println("Mail Saved")
        case MFMailComposeResultSent.value:
            println("Mail Sent")
        case MFMailComposeResultFailed.value:
            println("Mail Failed")
        default:
            break
        }
        self.dismissViewControllerAnimated(false, completion: nil)
    }
}

Fuente

Esqarrouth
fuente
0

Escribí un contenedor simple llamado KRNSendEmail que simplifica el envío de correo electrónico a una llamada de método.

El KRNSendEmail está bien documentado y agregado a CocoaPods.

https://github.com/ulian-onua/KRNSendEmail

Julian D.
fuente