Tuesday, December 25, 2012

iOS Programming 101: How To Send Email in Your iPhone App

Here comes another tutorial for our iOS Programming 101 series. Last time, we show you how to hide tab bar in navigation interface. In this tutorial, we’ll show you how easy you can let user send email in your app.
The iOS SDK has made it really easy to send email using the built-in APIs. With a few line of codes, you can launch the same email interface as the stock Mail app that lets you compose an email. In this tutorial, we’ll build a very simple app to show you how to send both plain text and HTML email using the iOS SDK.
SimpleEmail Tutorial Logo

Create a Simple View App with a Button

First, create a simple app with a view controller and a button. If you have no idea how to do it, you better revisit the Hello World tutorial. Let’s name the project as SimpleEmail. If you’ve successfully created your project, add a “Contact Us” button in the view.
SimpleEmail App with Contact Us Button
SimpleEmail App with Contact Us Button
What the app does is that it’ll show up the email interface when user taps the “Contact Us” button.

Connecting the Contact Us Button with Action

In the past tutorials, we used to add the action method manually in the header file of the view controller file. We then link the button and the action method in the Interface Builder.
This time, let us show you another way to add the action method (make sure you use Xcode 4.3 or up).
In the Project Navigator, select the “SimpleEmailViewController.xib” file to go to the Interface Builder. Switch to the Assistant Editor and hide the Utility area:
Show Assistant Editor
Show Assistant Editor and Hide Utility Area
Once you make the change, your Xcode environment should look like the below screen. The interface and its corresponding code are now shown side by side:
Assistant Editor Enabled
User Interface and Source Code Displayed Side by Side
Now we’ll add an action method for the “Contact Us” button. Press and hold the control key, click the “Contact Us” button and drag it towards the “SimpleEmailViewController.h”. As you place the pointer between the “@interface” and “@end” keywords, you should see a prompt that allows you to insert outlet and action.
Prompt to Let You Insert Outlet and Action
Prompt to Let You Insert Outlet and Action
Release the mouse button and Xcode prompts you to add the outlet/action. As we’re going to add the action method, select “Action” for “Connection” and name the method as “showEmail”. You can keep the event as “Touch Up Inside”. The “showEmail” method will be invoked when users lift up the finger inside the button.
Add action method showEmail
Add action method - showEmail
Once you confirm the change by clicking the “Connect” button, Xcode automatically adds the method declaration in the SimpleEmailViewController.h.
Added ShowEmail Action Method
Xcode Automatically Inserts the showEmail Method

Implementing the Email Interface

Next, import the “MessageUI.h” and implement the “MFMailComposeViewControllerDelegate” delegate in SimpleEmailViewController.h.
1
2
3
4
5
6
7
#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>

@interface SimpleEmailViewController : UIViewController <MFMailComposeViewControllerDelegate> // Add the delegate
- (IBAction)showEmail:(id)sender;

@end
Select the “SimpleEmailViewController.m” and we’ll implement the “showEmail” method and MFMailComposeViewControllerDelegate. Add the following code in the implementation file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
- (IBAction)showEmail:(id)sender {
    // Email Subject
    NSString *emailTitle = @"Test Email";
    // Email Content
    NSString *messageBody = @"iOS programming is so fun!";
    // To address
    NSArray *toRecipents = [NSArray arrayWithObject:@"support@appcoda.com"];
   
    MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
    mc.mailComposeDelegate = self;
    [mc setSubject:emailTitle];
    [mc setMessageBody:messageBody isHTML:NO];
    [mc setToRecipients:toRecipents];

    // Present mail view controller on screen
    [self presentViewController:mc animated:YES completion:NULL];

}

- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    switch (result)
    {
        case MFMailComposeResultCancelled:
            NSLog(@"Mail cancelled");
            break;
        case MFMailComposeResultSaved:
            NSLog(@"Mail saved");
            break;
        case MFMailComposeResultSent:
            NSLog(@"Mail sent");
            break;
        case MFMailComposeResultFailed:
            NSLog(@"Mail sent failure: %@", [error localizedDescription]);
            break;
        default:
            break;
    }
   
    // Close the Mail Interface
    [self dismissViewControllerAnimated:YES completion:NULL];
}
Line 3-7 of the above code define the email subject, message content and recipients. Line 9-13 creates the built-in MFMailComposeViewController. The MFMailComposeViewController class provides a standard interface that manages the editing and sending an email message. You can use this view controller to display a standard email view inside your application. We populate the fields of that view with initial values including the recipient email, subject and body text.
Line 13 of the code invokes the presentViewController to display the mail interface on screen.
The “didFinishWithResult:” is a method of the MFMailComposeViewControllerDelegate protocol. This method will be automatically called when the mail interface is closed (e.g. user cancels the operation). The result parameter tells you the result code when the mail composition interface is dismissed. For the sake of simplicity, we simply log the status in this example. In real world application, you should provide special handling for the result code (e.g. display an alert when the app fails to send the email).
Finally, line 41 dismisses the mail composition interface.

Adding the MessageUI Framework

However, this is not done yet. If you try to compile the app, you’ll end up with the below compilation error:
SimpleEmail Compilation Error
SimpleEmail App Compilation Error
The problem is that Xcode has no idea about what the “MFMailComposeViewController” is. Though “MFMailComposeViewController” is a built-in controller in iOS SDK, it’s developers’ responsibility to embed the necessary framework in your project. When the Xcode project is first created, it only comes with three core frameworks including UIKit, Foundation and CoreGraphics. The “MFMailComposeViewController” class is included in the MessageUI framework that you have to add manually.
To fix the error, we have to embed the framework in the project. In the Project Navigator, select “SimpleEmail” project and then select the “SimpleEmail” target under “Targets”. Click “Build Phases” at the top of the project editor. Then open the Link Binary With Libraries section.
Add Framework in Build Phases
Add Framework in Build Phases
Next, click the “+” button and select the “MessageUI.framework”. After you click the “Add” button, Xcode will include the MessageUI framework in the project.
Add MessageUI Framework
Add MessageUI Framework in Your Xcode Project
Now the error should have been fixed. Run your app and see how it works. Tapping the “Contact Us” button will show you the “Compose Email” interface with pre-populated content.
SimpleEmail App
SimpleEmail App

Composing HTML Email

The SimpleEmail app now only supports plain text email. You can easily enable the support of HTML email by changing the “isHTML” parameter in “setMessageBody” method from “N” to “Y”. Try to change the code in “showEmail” method to the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (IBAction)showEmail:(id)sender {
    // Email Subject
    NSString *emailTitle = @"Test Email";
    // Email Content
    NSString *messageBody = @"<h1>Learning iOS Programming!</h1>"; // Change the message body to HTML
    // To address
    NSArray *toRecipents = [NSArray arrayWithObject:@"support@appcoda.com"];
   
    MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
    mc.mailComposeDelegate = self;
    [mc setSubject:emailTitle];
    [mc setMessageBody:messageBody isHTML:YES];
    [mc setToRecipients:toRecipents];

    // Present mail view controller on screen
    [self presentViewController:mc animated:YES completion:NULL];

}
Compile and run your app again. With just a simple change, the SimpleEmail app now offers HTML support!
SimpleEmail App with HTML Support
SimpleEmail App with HTML Support
As always, leave us comment and share your thought about the tutorial. If you have any suggestion for the iOS Programming 101 series, feel free to let us know.

No comments:

Post a Comment