How to send an email in iOS

We can use the MFMailComposeViewController to bring up the same view controller that the Mail App uses when you write an new email. Using this method lets us populate the send-to, subject and email body.

The class part of the MessageUI framework. Using it will open the mail app on your device. Devices without mail sending capabilities will crash so we’ll check before we instantiate the controller.

Here’s how to do that:

    if ([MFMailComposeViewController canSendMail])
        MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
        mailer.mailComposeDelegate = self;
        [mailer setSubject:@"I've written a frigging Masterpiece!"];
        NSArray *toRecipients = [NSArray arrayWithObjects:@"", @"", nil];
        [mailer setToRecipients:toRecipients];
        UIImage *myImage = [UIImage imageNamed:@"yourimage.png"];
        NSData *imageData = UIImagePNGRepresentation(myImage);
        [mailer addAttachmentData:imageData mimeType:@"image/png" fileName:@"yourimage.png"];
        NSString *emailBody = self.emailField.text;
        [mailer setMessageBody:emailBody isHTML:NO];
        mailer.modalPresentationStyle = UIModalPresentationPageSheet;
        [self presentModalViewController:mailer animated:YES];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Failure"
                                                        message:@"Your device doesn't support the composer sheet"
        [alert show];

In addition we should conform to the MFMailComposeViewController protocol, so let’s set this in our ViewController.h file. We also need to import the MessageUI Framework while we’re here:

#import <MessageUI/MessageUI.h>
@interface ViewController : UIViewController <MFMailComposeViewControllerDelegate>

Don’t forget to add the framework itself via Build Phases (explained in the next article).

Dismissing the view controller

The mail view controller needs to be dismissed when it’s no longer needed. The system calls the delegate method didFinishWithResult when the operation is done. At this point we can check the error object to see what went wrong – I’m just going to dismiss the controller:

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

Demo Project

I’ve made a small (but well commented) demo project that will demonstrate this implementation:

Leave a Reply