Sending an email from your iPhone application is something which you normally want to do it asynchronously. But unfortunately, prior to iPhone 3.0, the only way to send email was using mailto:// url format. i.e,

[[UIApplication sharedApplication] openURL: @"mailto:john.appleseed@apple.com"];

The technique was clumsy for one reason.


It quits your app and launches mail. To our rescue, comes in-app email.

In-App email is not something new in iPhone 3.0 software. For the end users, it was available from day 1. Remember the Photos app? It sends your photos attached in the email message without quitting? But third party developers like us, were not given access to those private APIs.

In iPhone 3.0 Apple has exposed this private API with which you can send emails without quitting your application.

Sending an email with this technique might not be as easy as one single function call which we saw earlier, but at the same time it’s not complicated like “Push notification”. With less than say 10 lines of code, you can get the in-app email up and running in your own app. Now, let’s see how to do that.

I’m not going to attach any source code or like. The best source code that anyone can write is already available from Apple. Search for MailComposer or click the link below.


https://developer.apple.com/iphone/library/samplecode/MailComposer/index.html (link opens in new window)

There isn’t however a walkthrough though, which is why I thought I could bridge the gap ;-)

To summarize, there are 4 main steps (and 1 other not-so-important) in this.

1) Add the MessageUI Framework to your project

2) Add #import <MessageUI/MessageUI.h> line to the file where you want to use in-app email

3) The real code to show the UI as a modal dialog.

4) Implement a callback delegate so that you know when the user (and system) has finished sending the email.

Let’s get started.

Importing the MessageUI should be a cakewalk. On your XCode window,right click/cmd+click the “Frameworks” folder and click Add -> Existing Framworks. Choose the MessageUI from the path illustrated below.

Adding MessageUI Framework to XCode

Adding MessageUI Framework to XCode

Step 1 – Done

2) The second step needs no special explanation.

In your view controller, you will be using the classes in this framework. So #import the necessary header file, MessageUI/MessageUI.h

Do this #import on the h file rather than the m file as, you will be adding a delegate later (in step 4) to your ViewController.

Step 2 – Done

3)I’ve written a nifty little function that does the complete email sending logic.

The code is here. Feel free to use it in your apps, (attribution not necessary, though I would be happy if you do so)

-(void) showEmailModalView {
 
 MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
<strong> picker.mailComposeDelegate = self;</strong> // &lt;- very important step if you want feedbacks on what the user did with your email sheet
 
 [picker setSubject:titleText.text];
 
 // Fill out the email body text
 NSString *pageLink = @"http://mugunthkumar.com/mygreatapp"; // replace it with yours
 NSString *iTunesLink = @"http://link-to-mygreatapp"; // replate it with yours
 NSString *emailBody =
 [NSString stringWithFormat:@"%@\n\n&lt;h3&gt;Sent from &lt;a href = '%@'&gt;MyGreatApp&lt;/a&gt; on iPhone. &lt;a href = '%@'&gt;Download&lt;/a&gt; yours from AppStore now!&lt;/h3&gt;", content, pageLink, iTunesLink];
 
 [picker setMessageBody:emailBody isHTML:YES]; // depends. Mostly YES, unless you want to send it as plain text (boring)
 
 picker.navigationBar.barStyle = UIBarStyleBlack; // choose your style, unfortunately, Translucent colors behave quirky.
 
 [self presentModalViewController:picker animated:YES];
 [picker release];
 
}

The first step is to create the view for the email class. For that we use the MFMailComposeViewController.


Subsequent steps are to fill in the subject, (ToAddress, CC etc also can be filled from [picker setBlahblahMethods]) and messagebody. Usually, you leave the addresses to be filled by the user. Until the user fills the “To” field, the “Send” button will not be enabled on the Email sheet.

You can choose a color for the in-app email sheet. Unfortunately translucent sheet behave a bit quirky. For me the To address field was getting hidden beneath the translucent toolbar. :( I may be wrong.

Finally call the presentModalViewController to display the email sheet.

Step 3 – Done!!!

4) Now, you need to implement a delegate that will be called when the user taps the “Send” button on the mail interface. Luckily, it’s again a simple thing… :D

For this delegate to be called, you have to set the picker.mailComposeDelegate to self before calling the presentModalViewController (this line is shown in bold in step 3)

If you compile the app, XCode will complain that your “MyGreatAppViewController doesn’t conform to  MFMailComposeViewControllerDelegate protocol. Though it’s a warning and can be ignored, for the sake of writing “quality” app, add the “MFMailComposeViewControllerDelegate” to your protocol handler list like this in the header file.

@interface MyGreatAppViewController : UIViewController <MFMailComposeViewControllerDelegate> { }

This is the reason why I advised you to add the MessageUI header imports in the .h file in Step 2. Now in your .m file, add the following block of code that handles the delegate.

// Dismisses the email composition interface when users tap Cancel or Send. Proceeds to update the message field with the result of the operation.
 
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{ 
 // Notifies users about errors associated with the interface
 switch (result)
 {
 case MFMailComposeResultCancelled:
 break;
 case MFMailComposeResultSaved:
 break;
 case MFMailComposeResultSent:
 break;
 case MFMailComposeResultFailed:
 break;
 
 default:
 {
 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Email" message:@"Sending Failed - Unknown Error :-("
 delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
 [alert show];
 [alert release];
 }
 
 break;
 }
 [self dismissModalViewControllerAnimated:YES];
}

Relax! Not the whole block is important. just write the last line,

[self dismissModalViewControllerAnimated:YES]

and that will do. The other lines are given here for the sake of completion. You can handle those situations if you want.

As of now, there is no delegate method that would report the percentage of the mail that has been transmitted (so that you can display a progress like the Mail app. But hopefully, with subsequent releases of the SDK, apple could open them up as well.

Step 4 – Done!!!

Now, just call

[self showEmailModalView]

where you want the sheet to be shown. That’s it.

Now…. One more thing… ;-)

iPhone users have migrated to iPhone 3.0 (atleast over 75%). iPod touch users still haven’t (atleast at the time of writing this article). How will you handle a situation where in the user using your app is still running iPhone 2.x software?

Fortunately, Apple has provided a simple one-liner to tackle the situation. Just check it by calling canSendMail method

[MFMailComposeViewController canSendMail]

If canSendMail, then call my showEmailModalView function, otherwise, fall back to the tradional way. This handling is explained elegantly in Apple’s source code MailComposer.

https://developer.apple.com/iphone/library/samplecode/MailComposer/index.html (link opens in new window)

That’s it for this tutorial. Hope you enjoyed it and Thanks for visiting my blog,

Update: (28th August 2009)
Two commenters have asked me for sending email without showing the UI.
I think it’s not that easy. You have to use a SMTP client like http://code.google.com/p/skpsmtpmessage/
This blog explains how to send emails in the background without user intervention. But I’m not sure about Apple approving such apps however… :(

Follow me on Twitter

If you enjoyed this post, make sure you subscribe to my RSS feed!

No related posts.

  • Thomas C.

    I'm working with the MailComposer project and found your blog. I'm fairly new to iPhone development. In this project when the MFMailComposeViewController is presented I am trying to handle the send and cancel buttons. What IBAction or method do I have to handle to catch these two button events? My app sends the email, but I need a procedure to dismiss the MFMailComposeViewController.

    Thank you!

    • http://intensedebate.com/people/mugunthkumar mugunthkumar

      If you set
      picker.mailComposeDelegate = self; your controller will be notified of these events via, a delegate,

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

      If you don't set your controller (the class that calls the mailcomposer dialog) as the delegate, you won't get those callbacks.
      To dismiss the modal view, call
      [self dismissModalViewControllerAnimated:YES];
      inside the delegate method.

      I've explained this in Step 4.
      Hope my article is clear.
      Thanks for visiting.

      • ash

        Hi,

        Thank you very much for the post and the information provided. I tried this and it works fine.

        But, I'm struck with some problem. I have 4 views. The email sending part is the 4th view. Once email is sent, I need to display an alert saying "email sent" ans then show the second view.

        I have written code to show the alert in the case
        case MFMailComposeResultSent:

        [self dismissModalViewControllerAnimated:YES];
        Takes me to the 3rd view after displaying the alert. But, how will I show the 2nd view instead of 3rd?

        Waiting for your help.
        Thanks,
        ash.

        • ash

          Hey… I figured it out myself..

          [self.navigateController popViewControllerAnimated:YES]

          will do the trick !!!

          -ash

  • Thomas C.

    oops, posted too soon, got it ….

  • johnny

    Hello. Thank you for this great info! Keep up the good job!

  • Eric

    Hi,
    Is there a method to also send the email securely? Ie. encrypted?
    Thanks,
    Eric

    • http://intensedebate.com/people/mugunthkumar mugunthkumar

      It depends on your Email configuration settings. If your IMAP server supports (or requires) TLS, then every email u send is always sent over an encrypted channel. If it doesn't, even if you manually encrypt, it will not understand your data.
      However, If you are looking for a solution to send some data from the user back to your server (like a highscore from your game), consider using RESTful services rather than encrypting data and sending it as an email.
      My next blog post, which I currently writing is on consuming RESTful web services on iPhone.

  • Jordan

    Awesome post. You rock.

  • http://intensedebate.com/people/StevenDenenberg StevenDenenberg

    Hi,
    Thanks for the great post!! I want to use MFMailComposeViewController in my app, like in Apple's MailComposer example application, but …

    I don't want the user to be able to edit the "To:" field, in fact I don't want to display it at all. I don't want to display or have the user edit the CC or BCC fields, or even the Subject field. I want to be able to attach images, but I don't want them to be visible in the view. (In fact, I have another problem: I don't know how to dismiss the UI's keyboard other than clicking Send or Cancel).

    What I *really* want is to be able to populate the picker properties (Subject, toRecipients, AttachmentData) programmatically, and programmatically call the "Send" button, so the email gets sent without even showing the UI.

    Is there a way to do that? MFMailComposeViewController is the only way I know to send email with image attachments. If MFMailComposeViewController can't be used like that, can I get this functionality another way?

    Thanks for any help.
    /Steve

    • http://intensedebate.com/people/mugunthkumar mugunthkumar

      Post updated with your questions. Thanks for visiting my blog :D and thanks for your interesting question… :D

  • http://wso2.org/wiki/display/~billbartmann20 Bill Bartmann

    Excellent site, keep up the good work

  • https://wso2.org/wiki/display/~kassandrai07 Bill Bartmann

    I’m so glad I found this site…Keep up the good work

  • http://wso2.org/wiki/display/~billbartmann20 Bill Bartmann

    Cool site, love the info.

  • cole

    did you ever figure this out:

    I don't want the user to be able to edit the "To:" field, in fact I don't want to display it at all. I don't want to display or have the user edit the CC or BCC fields, or even the Subject field. I want to be able to attach images, but I don't want them to be visible in the view

    also, to dismiss the MFMailComposeViewController, implement

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

    • http://intensedebate.com/people/mugunthkumar mugunthkumar

      To have utmost control on your email sending, use a custom SMTP mail sender like, http://code.google.com/p/skpsmtpmessage/

      BTW, this post has implemented didFinishWithResult (sec 4)

  • http://mcdonaldscoupon.jimdo.com mcdonalds coupons

    Thanks much for this good piece of text.

  • faisal

    Hi,
    thankx for nice tutorial.
    I have run the apples sample code,
    but i want to attach files or images at run time, how i can do it?

    thanks in advance

  • http://intensedebate.com/people/mugunthkumar mugunthkumar

    Use these two lines of code. You should know the filePath and it's mimeType

    NSData *data = [[NSFileManager defaultManager] contentsAtPath:filePath];
    [picker addAttachmentData:data mimeType:mimeType fileName:fileName];

  • http://www.iphone.sanniv.com Sanniv

    How to receive emails using pop service in iPhone programmetically?
    Anyone knows?

  • Paul

    Great post, have tried your way for the email body rather than from contents of html file but I still get the message being send encoded so the links as in your example (and mine) do not come out correct. Even though it is set to isHTML:YES I do not get visible text. The receeved email contains nothing to say it is HTML in fact the header says text/plain but the content is encoded?

    Any ideas??

  • Marcelo

    Thank you!!!

    But how to send email without showing the UI?

    The blog http://vafer.org/blog/20080604120118 shows it for cocoa, not for cocoa touch.

    And using a SMTP client like http://code.google.com/p/skpsmtpmessage/ is too big.

    Thanks for any help.

    • Shane

      Hiye, did you figure out how to do this??

  • Simon

    Just want to say a big Thank You for posting this. Definitely a big help and resource for me.
    Thanks again!

  • Chris

    Hi Im kinda New to iphone development and I want use MFMailComposeViewController to take the text/notes that are on the screen and have them automatically applied to the subject portion of the screen is this possible and if so how would I implement it. Thank for the great tutorial and any and all help you can provide.
    Chris

  • http://guitarbeginnerpacks.com/contact Delfina Ganer

    Hi I believe the data written on your internet blog is fundamental, I have book marked you =D

  • Pingback: iPhoneOS iPad Development Resources | de

  • http://tinumono.insanejournal.com/279.html Victoria Renda

    Pretty nice post. I just stopped by by your site and wanted to say that I have really enjoyed checking your content. Any way, I’ll be subscribing to your RSS feed and I hope you write again shortly!

  • vetsAreFun

    I am very new to iPhone app development.. This is my very first one. I am trying to implement your solution here and have a question. Inside the Frameworks tab, I don’t have the MessageUI Framework. I am using the most recent version of XCode. I know it is something simple, but.. Can someone give me a hand. Also my screen does not look like the one in this article, guessing newer version on my box.

  • Rahul K

    Hi, I am trying to auto populate Recipient in mail composer once I select the person's email address from the address book.
    I am not sure how I can do this? Is there a way I can do this?
    Can anyone please help me with this.
    Thanks,

  • michel

    How to receive emails using pop service in iPhone programmetically?
    Anyone knows?
    (…same question already posted by Sanniv 20 weeks ago, I can't find any answer too,
    may be not possible …or just obvious !?)

  • Pingback: iPhone Tutorial: Elegant way to send formatted In-App email | blog.mugunthkumar.com

  • Matt

    Awesome tutorial. Saved me a lot of time integrating feedback email into my App. Thanks again.

  • Pingback: iPhone Tutorial: How to send In-App SMS | MK Blog

  • http://twitter.com/stlplace @stlplace

    Regarding to earlier question:

    Regarding to earlier question:
    =======================
    How to receive emails using pop service in iPhone programmetically?
    Anyone knows?
    (…same question already posted by Sanniv 20 weeks ago, I can't find any answer too,
    may be not possible …or just obvious !?)
    ===============================
    this works for me on real iPhone. I assume previous user encountered this problem on iPhone simulator?

  • http://keephide.us vpn solution

    I was able to set up a Windows VPN using XP home. However it is not terribly reliable. I would recommend a product/service called Hamachi from a Log Me In Inc. It is an excellent zero configuration VPN, free for home use but they do charge for commercial use. I use their remote control product, Logmein, extensively. It too is free and an excellent remote control product. Hope this helps.

  • http://hubpages.com/hub/blogging-can-be-fun Mignon Callarman

    I venture there are lots of individuals like me, who come across various great blogs or websites by chance. Your blog appears to feature a solid community and a sound blogosphere presence. Its positive to have engrossing and various positions on issues.

  • http://parttimejobshiring.net/ Lissette Merrbach

    Just to let you know..
    . your website looks extremely strange in Mozilla on a Mac

  • http://moredecisive.com Steve Steinitz

    Really helpful. Thanks for describing the framework, headers and delegation in detail.

  • http://thickgirls.org/ Lauren Corp

    Is that true? I’ll spread this info. Anyway, great article

  • Andrew Colsch

    GREAT tutorial! Worked for me the first time I tried it, no questions asked. Thanks a ton :)

  • http://web.hc.lv deni2s

    “(this line is shown in bold in step 3)” – no, it’s not.

  • Satupled66

    Thaaannk you!!!!!! Worked like a charm on my already working app!!

  • http://www.leeyoonhyun.com Lee YoonHyun

    Good!!

  • Dan

    Very nice article – good job!
    I have one issue. After all the line gets executed, the app crashes. The console has just Program received signal: “EXC_BAD_ACCESS”. It did not send the email either.
    Any help is appreciated. Thanks
    Dan

    • Dan

      It does send email. The control goes to the mailComposeController delegate method and then the app exits with the ‘EXC_BAD_ACCESS’ error.

  • guru

    Application tried to present a nil modal view controller on target. Why would I be getting that?

    • guru

      forget to mention that its on the iPAD….

  • Mohit

    i want to display my icon file in the mail… 
    how can i do it ?

  • Beau

    Thanks for this but I get this Error:

    Apple Mach-O Linker (id) Error
    Undefined symbols for architecture i386:
      “_OBJC_CLASS_$_MFMailComposeViewController”, referenced from:
          objc-class-ref in EmailTestViewController.o
    ld: symbol(s) not found for architecture i386
    collect2: ld returned 1 exit status

  • http://twitter.com/PeterNormanJ Peter Jenkins

    Beau,

    You have to link with the MessageUI library.

    Project->Targets->Build Phases->Link Binary With Libraries->Plus icon->MessageUI.framework

  • Pingback: Objective-C / Cocoa : Sending Email | Love Life, Live Code, Music Is The Best!

  • Pingback: BiOM's iOS Page » Blog Archive » Sending In App Tweets

  • Mike Matsui

    Hi – I have 2 questions

    Can any other e-mail clients be integrated for this in-app mail eg.gmail,yahoo,outlook?

    Is it possible to write the content of this e-mail in natural handwriting and send it as well?

    Many thnx

    • Satupled66

      If you mean other apps instead of Mail app, I’m afraid the answer is no. What you can do is associate your gmail, yahoo or work account to the Mail app and use it as predefined.

      I’m not sure i quite understand your second question, what I think you mean is: drawing an image and sending it as the content of the mail right? if that is the case you should first create a class that retuns an image and when you are done drawing it, open the Mail modal window. The only way I guess you could send it is as an attachment but I don’t know if there is a way to attach a file to a mail sent this way.

      Hope it helps

  • Pingback: iOS Tutorial: Sending In App Tweets | MKBlog

  • http://www.jatheon.com/ groupwise email archiving

    It actually helped me to clear up some other issues I had. Great text. 

  • Pingback: CoffeeFast Attributions | thumblines

  • http://twitter.com/Matt_Sich Matt Sich

    Great tutorial! I have a problem with it though… It works the first time but if I exit out of the email and then try to compose a message again, the app crashes. I’m building for iOS5 and “release” is not an option. How would i go about releasing the view completely (because I think that’s what the problem is)? 

    • http://twitter.com/Matt_Sich Matt Sich

      ah, fixed my problem. I was using a mapView initially before the email pane rolled in. I had to add back the observer:
       [self.mapView.userLocation addObserver:self 
                                      forKeyPath:@"location" 
                                         options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) 
                                         context:nil];

  • Pingback: iPhone Tutorial: How to send In-App SMS « maroueneboubakri