It’s often useful to provide a way for users of your apps to send email. The applications that allow you to add an email feature to the inside an app are almost limitless, but to learn the basics of how it works, we’ll build an app in this post that you can use to let your users contact you for support. We’ll even see how to include the version of iOS and the type of device our app is running on in the message body.
Open Xcode and from the File menu, select New, and then New Project… A new workspace window will appear, and you will be presented with several application templates to choose from.
On the left-hand side, select Application from the iOS section. Select Single View Application and click the Next button.
On the next pane, enter MailMe for the Product Name and com.myappcompany as the Company Identifier. (Feel free to substitute your own product name and company identifier).
Leave the Class Prefix as is. It should be blank – XYZ is just a placeholder hint.
Make sure only Use Automatic Reference Counting and Use Storyboards are checked.
Set Device Family to iPhone, and click Next.
A new pane will appear asking you where you would like to save the project. XCode will create a MailMe project folder inside the directory you select.
Once the project is created, Xcode will open a workspace window with your new project.
We’re going to design our user interface with a toolbar containing a button that will allow our user to send a support email. We’ll prefill the email header with our support address and a custom subject line to make things even easier for our user. Before setting up the user interface, we’ll first need to provide a method that will be called when the button is pressed. In the Files and Groups pane, click on ViewController.m and add the following method directly under ViewDidLoad:
NSLog(@"sender %@",[sender description]);
IBAction is a macro that makes our method available to Interface Builder, which we’ll need when setting up the user interface. When the button calls our method, it passes a reference to itself as sender. We won’t be using that reference in this project, but it’s good to get into the habit of coding your button actions this way.
Creating the User Interface
Now click on MainStoryboard.storyboard. After it opens in Interface Builder, select the View object, click on the Attributes Inspector and then change the view’s background color to a color of your choosing.
Next go to the Object Library located on the lower right-hand side of the workspace and drag a Toolbar to the bottom of the view. The toolbar comes with one button already attached, so double click on it and change its label to “Email Support.” Figure C shows the situation so far.
Next, we will need to connect the button with our emailSupport: method. Control drag from the button over to View Controller as shown in Figure D. When you release the mouse, a popup will appear. Select emailSupport: to make the connection.
Now build and run the app and tap the button. If all is well, you should see something similar to the following in the console log:
2013-04-17 13:43:38.895 MailMe[59566:c07] sender <UIBarButtonItem: 0x758c650>
Adding mail functionality
The email methods we’ll be using are part of the MessageUI Framework, so we’ll need to add that to our project. The steps are shown in Figure E. Click on the Project in the Files and Groups pane (1), then on the MailMe Target (2), then on “Build Phases” (3), and finally the “+” button under the “Link Binary With Libraries” section (4).
Begin typing the word “message” into the “Choose frameworks…” field until MessageUI.framework appears. Select it and click on Add. (Figure F)
To actually create and send an email, we will need to create an instance of MFMailComposeViewController and present its view, which is where the user will actually create and send the message. We will then dismiss the view after the user presses either “Send” or “Cancel”.
Let’s go back to ViewController.m and make the necessary changes. The first thing we need to do is add the MessageUI header to our class, so add the following line (bold text) just under the import of ViewController.h.
ViewController will need to conform to the MFMailComposeViewControllerDelegate protocol so that we can be notified when the user is finished. To do so, make the following change to the interface declaration:
@interface ViewController () <MFMailComposeViewControllerDelegate>
Then add the following code to emailSupport:
NSString *iOSVersion = [[UIDevice currentDevice] systemVersion];
NSString *model = [[UIDevice currentDevice] model];
NSString *version = @"1.0";
NSString *build = @"100";
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
[mailComposer setToRecipients:[NSArray arrayWithObjects: @"firstname.lastname@example.org",nil]];
[mailComposer setSubject:[NSString stringWithFormat: @"MailMe V%@ (build %@) Support",version,build]];
NSString *supportText = [NSString stringWithFormat:@"Device: %@\niOS Version:%@\n\n",model,iOSVersion];
supportText = [supportText stringByAppendingString: @"Please describe your problem or question."];
[mailComposer setMessageBody:supportText isHTML:NO];
[self presentViewController:mailComposer animated:YES completion:nil];
And finally, add the delegate method that will be called after “Send” or “Cancel” has been tapped by the user.
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
[self dismissViewControllerAnimated:YES completion:nil];
Now build and run the app and tap on “Email Support”. The results should look similar to Figure G.
You might want to run the app on a real device and note the device type and iOS version. The device version will not be very specific with the code we’ve used here, but in a future post we’ll see how to determine that much more precisely.
As you can see, the iOS SDK does all of the heavy lifting and makes it very easy to add email functionality to your app. For more advanced features, be sure to read the MFMailComposeViewController class reference in Apple’s documentation.