iOS SDK: Send E-mail In-App

iOS SDK: Send E-mail In-App

Tutorial Details
  • Technology: iOS SDK
  • Difficulty: Intermediate
  • Completion Time: 30 - 45 Minutes

In this iOS SDK tutorial, I’ll demonstrate how to allow your users to send e-mail without leaving your application using the MFMailComposeViewController class. We will setup an e-mail template with recipients, a subject, body text, and even an image attachment.

The iOS SDK provides an easy to use, standard interface to allow your users to send and edit e-mail from within your own application. To do so, you will need to use the MFMailComposeViewController class. This view controller displays a standard mail interface and also provides the functionality to respond to user events performed on that interface. For instance, you the class will notify you if the user hit “send” or “cancel”.

Note: MFMailComposeViewController is only available on iOS 3.0 or later.

So, how does it work? Follow the steps in this tutorial to find out.


Step 1: Create a New Xcode Project

Open Xcode and select “Create a new Xcode project”. Select View-based Application and then click Next. Enter a name for your project. I called mine @”Mail”. Enter your Company Identifier and make sure you selected “iPhone” for Device Family, because we are going to make an iPhone app. If you are done, click Next. Choose a place to save your project and click Create.

    New Project

Step 2: Add the Mail Button

Open the “MailViewController.xib” file and drag a button into the view. Set the title of the button to “Mail”. Now select the middle button of the Editor to show the “Assistant editor”, so we can add an action to the button we just created.

    Assistant Editor

Select the button and CTRL-drag to the “MailViewController.h”. In the pop-up that is displayed, enter “openMail” for name and make sure to set the connection type to “Action”, because we want to make an action and not an outlet.

    Connection

Step 3: Import the MessageUI Framework

In the navigator area of Xcode 4, select the project name. Next, select the current target (“Mail” in this case), and then select the “Build Phases” tab. Expand the “Link Binary With Libraries” option, and then click the “+” button to add a new framework. Type “message″ into the search box, and select the MessageUI.framework option that appears in the list. Click “Add” to include this framework in the linking phase of your project.

Now that you have added the MessageUI framework into your project, you need to import that framework into the view controller that will use the MFMailComposeViewController, so, in our case, MailViewController.h.

Go to this file and modify the code to read as follows:

#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>
@interface MailViewController : UIViewController <MFMailComposeViewControllerDelegate>
- (IBAction)openMail:(id)sender;
@end

As you can see, we also declared the MFMaileComposeViewControllerDelegate in the above code. We will use this delegate to see the result of the mail.


Step 4: Add Project Resources

Drag the following image to the “Supporting Files” folder in your project. Make sure “Copy items into destination group’s folder (if needed)” is checked before clicking finish.

    MobileTuts+ logo

Step 5: Check if Device is Able to Send E-mail

Open the “MailViewController.m” file and scroll down to the openMail: action and modify the code to read as follows:

- (IBAction)openMail:(id)sender
{
    if ([MFMailComposeViewController canSendMail])
    {
    }
    else
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Failure"
                                                        message:@"Your device doesn't support the composer sheet"
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];
        [alert release];
    }
}

Here we check if the current device is able to send e-mail with the canSendMail class method of MFMailComposeViewController. You should always call this method before you open the mail interface. If the device is not able to send e-mail, you should notify the user (I’ve used a UIAlertView for this).


Step 6: Show the Mail Interface

If the device is able to send e-mail, we display the mail interface. Go to the openMail: action and modify the code to read as follows:

- (IBAction)openMail:(id)sender
{
    if ([MFMailComposeViewController canSendMail])
    {
        MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
        mailer.mailComposeDelegate = self;
        [mailer setSubject:@"A Message from MobileTuts+"];
        NSArray *toRecipients = [NSArray arrayWithObjects:@"fisrtMail@example.com", @"secondMail@example.com", nil];
        [mailer setToRecipients:toRecipients];
        UIImage *myImage = [UIImage imageNamed:@"mobiletuts-logo.png"];
        NSData *imageData = UIImagePNGRepresentation(myImage);
        [mailer addAttachmentData:imageData mimeType:@"image/png" fileName:@"mobiletutsImage"];
        NSString *emailBody = @"Have you seen the MobileTuts+ web site?";
        [mailer setMessageBody:emailBody isHTML:NO];
        [self presentModalViewController:mailer animated:YES];
        [mailer release];
    }
    else
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Failure"
                                                        message:@"Your device doesn't support the composer sheet"
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles: nil];
        [alert show];
        [alert release];
    }
}

First we create a MFMaileComposeViewController and call it “mailer”. We set the mailComposeDelegate to self, so we can see the result of the mail. The subject is set to “A Message from MobileTuts+”. As you can see, the toRecipients is of the type NSArray. This is because you can add multiple recipients. I added two fake email addresses, but of course you can put any address you like. After that, we store an image as an NSData object, because we cant send a UIImage directly. Then we add the NSData object as an attachment to our e-mail. We set the type to a png image and the fileName to “mobiletutsImage”. This means that when the receiver saves the image, it will be saved under the name “mobiletutsImage”. The last thing we do is show the mailer before releasing the mailer object.


Step 7: Check the Result and Dismiss the View

You need to manually dismiss the mail interface in response to a delegate method call. Add the following code under the openMail: action:

- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
	switch (result)
	{
		case MFMailComposeResultCancelled:
			NSLog(@"Mail cancelled: you cancelled the operation and no email message was queued.");
			break;
		case MFMailComposeResultSaved:
			NSLog(@"Mail saved: you saved the email message in the drafts folder.");
			break;
		case MFMailComposeResultSent:
			NSLog(@"Mail send: the email message is queued in the outbox. It is ready to send.");
			break;
		case MFMailComposeResultFailed:
			NSLog(@"Mail failed: the email message was not saved or queued, possibly due to an error.");
			break;
		default:
			NSLog(@"Mail not sent.");
			break;
	}
        // Remove the mail view
	[self dismissModalViewControllerAnimated:YES];
}

In this delegate method, we check the result of having displayed the mail view controller with a switch statement and then dismiss the view controller with an animation. In the above code, I’ve simply printed an NSLog message with the results, but the point is that you could respond dynamically to the user’s action.


BONUS: Make it Work for iPad

On an iPad it looks nice to show the mail interface in a page sheet presentation. You can do that by adding the following line of code just above [self presentModalViewController:mailer animated:YES];:

mailer.modalPresentationStyle = UIModalPresentationPageSheet;
    iPad mail interface

Wrap Up

I hope you enjoyed this tutorial. If you have any feedback or requests for additional iOS content from me, please leave a comment below!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • Adawi

    Hello,

    How I can attach PDF file ?

  • http://ios-blog.co.uk Liam Amster

    This is a great tutorial, I would also like to know how to attach a PDF like adawi.

    Also, I think I may have missed it but how did you get the logo to appear as a signature?

    One other last question, ive been following this tutorial (http://ios-blog.co.uk/iphone-development-tutorials/how-to-make-a-magazine-app-in-ios-part-i/) to create a magazine style app. Would it be possible to email the magazine if i incorporated your code into it and if it were saved as a pdf? or maybe as an image.

    What would be the best way to handle this type of action?

    thanks

  • http://www.neoactiva.com Gus Pineda

    Great tutorial!, how can I hide To, Cc, Bcc Fields?

  • Iain Munro

    Afternoon

    Thanks for the tutorial.

    On my server, I have a NSString called myURL_email.

    What I want to do is call the mail function and have it populate the email address relating to a particular person as opposed to a set person.

    I changed this:

    NSArray *toRecipients = [NSArray arrayWithObjects:@"myURL_email", nil];

    But I get nothing in the To box.

    Any ideas ?

    Iain

    • Jeroen van Rijn
      Author

      I’m glad you liked it!

      First you have to change:

      NSArray *toRecipients = [NSArray arrayWithObjects:@"myURL_email", nil];

      to:

      NSArray *toRecipients = [NSArray arrayWithObjects:myURL_email, nil];

      because myURL_email is already an NSString, you don’t need to add the @” and “. You should get myURL_email in the to recipients box, but because you say you get nothing in the to recipients box, I think you forgot to add the following line :

      [mailer setToRecipients:toRecipients];

      I hope this can help you!

  • Ram

    Thank you very much…very useful stuff.

  • m

    thanx for the great tutorial ,,

    stupid question,,
    I just used the source code for now ,,but its not sending emails even its not giving any alert,,
    is that b/c am using the simulator ?!! or it should work in the simulator too!!

    thnx alot

    • http://twitter.com/#!/iOSPlayIt Jeroen van Rijn
      Author

      Hey,

      That’s because your are using the simulator. It will only send the email on a device.

  • Neil

    Great tutorial thanks Jeroen.

    The problem I’m having is that when I run it in iPhone 5.0 Simulator there are leaks when sending and saving a draft. Is there a solution to this?

    • Tobias

      Hi!

      First and foremost, thanks for this amazing tutorial, really cleared a few things up for me.

      Is there any way to ‘just’ attach the image rather than including it in the body? I’m working on an app that attaches several images to the mail before sending it and having them inline just looks catastrophic!

      Thanks!

    • Pierre

      Just as Neil (December 9, 2011 at 4:58 am)
      I am having this leak problem. Did some one allready solved that?

      • Neil

        Hi Pierre, no fix as yet. Have you had any luck?

  • http://walltilessydney http://www.sydneytiles.net.au/

    I was recommended this website by my cousin. I’m not sure whether this post is written by him as nobody else know such detailed about my problem. You are amazing! Thanks!

  • Thompson

    Very useful to see al the pieces in place like this; you have made a valuable contribution to the internet!

  • ali

    Hi.at first thanks for shared code.i want send email but i dont want see
    https://d339vfjsz5zott.cloudfront.net/iOS-SDK_MFMailComposeViewController/MFMailComposeViewController_iPadMailInterface.png
    this view.
    when i clicked sent it should go directly toRecipients. How can i do that? Have an idea?

  • Rj

    Really very nice tutorial
    Thanks a lot.
    Keep it up.

  • http://www.brandsexclusive.com.au Steve

    Thank you! This was exactly what I was looking for. Have now integrated into my app

  • Al

    great tutorial! I was able to embed this to my program and it works great.. just a few question and would be appreciated if it will be answered.
    a. can you have this work without showing the email.. so instead the user will only hear the sent email.. i will encode the To, Subject and the email body..
    b. can i embed an html code that consist of graphics? how can i make sure the graphics shows up on the app? do I put it on the support files?

    thanks in advance

    • http://twitter.com/#!/iOSPlayIt Jeroen van Rijn
      Author

      Thanks!
      To answer your questions:
      A) You can do that, but unfortunately I don’t now how.
      B) Yes you can add HTML to your mail. I’m not exactly sure, but I thought you can add it with the following line of code:
      [picker setMessageBody: isHTML:];

      I hope this can help you!

      • Vikash

        I want to make available my contacts from my own mail compositor i am using my own to, cc , bcc and body section.
        So can i make users to available contacts on key press of to textbox ??
        And i also want to make user to attach pdf file with mail .. Is it possible ????

  • Rhez Ann

    Nice tutorial! but my device doesn’t support the composer sheet? Does anybody knows why ? I’m using an iphone 3g.

  • Moe

    great tutorial! The only problem I have is that I don´t get back to the app after sending or cancelling the send-job. Instead a black screen appears when the NSlog should appear and I should get back to the app. Any solution for this?

    • Moe

      forgot: on the ipad it works fine, the problems only appear on the iphone (IOS 5.1)

  • Wagner

    Congratulations, great tutorial.

    Can I add this in an existing project? If yes, just add the file to the main root of the project?

    Cheers,

  • Vikash

    I want to make available my contacts from my own mail compositor i am using my own to, cc , bcc and body section.

    So can i make users to available contacts on key press of to textbox ??
    And i also want to make user to attach pdf file with mail .. Is it possible ????

  • Faruzalor

    Can you attach a PDF rather then an image?

  • Victor

    i did all of the tutorial but i didnt receive anything in my inbox, im using the simulator, it is some way to check that it really works in the simulator

  • Jesus

    Muy buen tutorial, funciona perfecto y esta muy bien explicado. Gracias por hacernos la vida mas facil un saludo.

  • Jordan

    Did anyone solve the .pdf attachment problem? I’m trying to do that as well…

  • Thuan Hoang

    I want change from mail as a email, not email set in my iPhone.
    Can i do it.
    Sorry, my English is not good

  • Logan

    This doesn’t seem to work on Xcode 4.5 / iOS6. Can you help me with this?

  • jep

    hello. thank you for your post. i would just want to ask why didn’t i receive the mail i have sent to my account? but the log was “Mail send: the email message is queued in the outbox. It is ready to send.” what did it mean? thank you. :-)

  • Cristina

    Very useful, many thanks from Madrid, Spain.

  • sati

    thanks man.. very simple article..

  • Jenny Huang

    there is no error in my project but i cant get the mail i sent to my email. please tell me how ASAP, Urgent!!

    • ilan lewin

      An important note that is somehow missing from the article !!
      The iphone simulator does not send email. Only a real device will !!!

  • Gik

    On the iPad the
    mailer.modalPresentationStyle = UIModalPresentationPageSheet;
    line does not work (even from the posted code).

    (Maybe it’s a iOS6 thing)
    Any ideas?

  • Orlando

    great work!

  • crazymoy

    Excelent!! pretty simple and useful, Thanks!!!

  • http://www.facebook.com/people/Bharath-Rajakumar/1195670908 Bharath Rajakumar

    thank you.. great share !! I got to send mail from my app !!

    too bad that this is feature works only an ios device…what a bummer !!

  • remsen

    This works great. Thank you. Is there a way to avoid the modal email screen and just send a generic email? I am looking to have automated (non-editable by user) emails sent from the app. Thanks!