Make Better Things



I like to make better things.

how to send in app email in iPhone SDK

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

But there is a problem with this approach. It quits your app and launches mail. To our rescue, comes in-app email.

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.

You can find the sample source code here – https://developer.apple.com/iphone/library/samplecode/MailComposer/index.html

Step 1:

Add the MessageUI Framework to your project

Step 2:

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

Step 3:

Here is the real code -

-(void) showEmailModalView {

 MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
 picker.mailComposeDelegate = self; // 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 = @"https://www.makebetterthings.com/mygreatapp"; // replace it with yours
 NSString *iTunesLink = @"http://link-to-mygreatapp"; // replate it with yours
 NSString *emailBody =
 [NSString stringWithFormat:@"%@nn<h3>Sent from <a href = '%@'>MyGreatApp</a> on iPhone. <a href = '%@'>Download</a> yours from AppStore now!</h3> ", 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.

Finally call the presentModalViewController to display the email sheet.

Step 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…

For this delegate to be called, you have to set the picker.mailComposeDelegate to self before calling the presentModalViewController.

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<strong> <MFMailComposeViewControllerDelegate></strong> { }

This is the reason why I advise you to add the MessageUI header imports in the .h file. 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];
}

Now, just call

[self showEmailModalView]

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

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.