Como posso enviar e-mails de um aplicativo para iPhone

242

Quero enviar um email do meu aplicativo para iPhone. Ouvi dizer que o SDK do iOS não tem uma API de email. Não quero usar o seguinte código, pois ele sairá do meu aplicativo:

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

Então, como posso enviar um email do meu aplicativo?

Khushi
fonte

Respostas:

430

No iOS 3.0 e posterior, você deve usar a MFMailComposeViewControllerclasse e o MFMailComposeViewControllerDelegateprotocolo, que estão escondidos na estrutura do MessageUI.

Primeiro adicione a estrutura e importe:

#import <MessageUI/MFMailComposeViewController.h>

Então, para enviar uma mensagem:

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];

Em seguida, o usuário faz o trabalho e você recebe o retorno de chamada do delegado a tempo:

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

Lembre-se de verificar se o dispositivo está configurado para enviar email:

if ([MFMailComposeViewController canSendMail]) {
  // Show the composer
} else {
  // Handle the error
}
PeyloW
fonte
5
+1. As estruturas que precisam ser importadas são mencionadas aqui ( mobileorchard.com/… ).
Dan Rosenstark
71
Para poupar o salto, você precisa #import <MessageUI / MFMailComposeViewController.h>
TomH 5/10
22
Apenas observe que, já que esta resposta foi escrita, os métodos do UIViewController presentModalViewController:animated:e dismissModalViewControllerAnimated:foram marcados como obsoletos - em vez disso, os métodos de substituição baseados em blocos presentViewController:animated:completion:e dismissViewControllerAnimated:completion:devem ser usados.
2
E não se esqueça delegado set em .h @interface viewController : UIViewController <MFMailComposeViewControllerDelegate>
Nazir
18
E em IOS 6 [self presentModalViewController:controller animated:YES]; substitua [self presentViewController:controller animated:YES completion:nil]; e [self dismissModalViewControllerAnimated:YES]; substitua-o por [self dismissViewControllerAnimated:YES completion:nil];
Nazir
61

O MFMailComposeViewController é o caminho a seguir após o lançamento do software iPhone OS 3.0. Você pode olhar o código de exemplo ou o tutorial que escrevi .

Mugunth
fonte
2
Post impressionante por Mugunth. Muito bem, amigo!
21209 Jordânia
1
É realmente incrível. Obrigado. Eu projetei uma visualização especialmente para aceitar o email e o assunto do usuário. Ao implementar o mesmo código, novamente mostramos uma visão semelhante. pode invocar o método delegado do meu botão de evento para a imprensa na classe controlador de vista Obrigado por sua ajuda, Shibin
smakstr
Fiz o download do mesmo código de exemplo, mas ele não envia nenhum email. Ele solicita apenas que o email foi enviado com êxito, mas nenhum email foi recebido. Eu tentei adicionar a estrutura MessageUI que parecia vermelha por padrão, mas ainda assim o aplicativo não está enviando o email. Qualquer ajuda nesse sentido será muito apreciada. Estou testando o aplicativo no simulador.
Ravi Shankar
Não é possível enviar email do simulador.
precisa saber é o seguinte
20

Gostaria de acrescentar algumas coisas aqui:

  1. O uso do URL mailto não funcionará no simulador, pois o mail.app não está instalado no simulador. Mas funciona no dispositivo.

  2. Há um limite para o comprimento do URL mailto. Se o URL tiver mais de 4096 caracteres, o mail.app não será iniciado.

  3. Há uma nova classe no OS 3.0 que permite enviar um email sem sair do aplicativo. Veja a classe MFMailComposeViewController.

Jeff Atwood
fonte
13

Se você deseja enviar um email do seu aplicativo, o código acima é a única maneira de fazê-lo, a menos que você codifique seu próprio cliente de email (SMTP) dentro do seu aplicativo ou que um servidor envie o email para você.

Por exemplo, você pode codificar seu aplicativo para chamar um URL no servidor que enviará o email para você. Então você simplesmente chama o URL do seu código.

Observe que, com o código acima, você não pode anexar nada ao email, o que o método do cliente SMTP permitiria, assim como o método do lado do servidor.

Genericrich
fonte
12

Abaixo, o código é usado no meu aplicativo para enviar e-mail com um anexo, aqui os anexos são uma imagem. Você pode enviar qualquer tipo de arquivo, apenas o que você deve ter em mente é que foi necessário especificar o 'mimeType' correto

adicione isso ao seu arquivo .h

#import <MessageUI/MFMailComposeViewController.h>

Adicione MessageUI.framework ao seu arquivo de projeto

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];

O método Delegate é como mostrado abaixo

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

Este é o código que pode ajudá-lo, mas não se esqueça de incluir a mensagem ui framewark e incluir o método 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];
    }
mandíbula
fonte
Muito obrigado! Exemplo muito útil com corpo HTML.
Resty
4

Swift 2.2. Adaptado da resposta da 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)
    }
}

Código do 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
fonte
4

Para enviar um email a partir do aplicativo do iPhone, você precisa fazer a lista abaixo da tarefa.

Etapa 1: Importar#import <MessageUI/MessageUI.h> Na sua classe de controlador para a qual você deseja enviar um email.

Etapa 2: adicione o delegado ao seu controlador como mostrado abaixo

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

Etapa 3: adicione o método abaixo para enviar email.

 - (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.
}
}

Etapa 4: implementar o delegado MFMailComposeViewController

- (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
fonte
esta resposta fornece alguma informação nova que ainda não esteja incluída em uma das respostas 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
fonte
1

Aqui está uma versão 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)
    }
}

Fonte

Esqarrouth
fonte
0

Eu escrevi um invólucro simples chamado KRNSendEmail que simplifica o envio de email para uma chamada de método.

O KRNSendEmail está bem documentado e adicionado ao CocoaPods.

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

Julian D.
fonte