As a part of an iPhone app I’m presently working on I was confronted with an apparently simple problem, which turned out to be more difficult than I thought.
Except it was simple, once you knew how to do it.
Question
How do I send a tabular report via e-mail in the iPhone SDK?
Short answer
Use a mailto url + stringByAddingPercentEscapesUsingEncoding + HTML.
Longer answer
So far (iPhone OS 2.2) the de facto way to send e-mail on your iPhone application is using a mailto url.
NSURL *url = [[NSURL alloc] initWithString:
@"mailto:me@me.com?subject=subject&body=Hi"];
[[UIApplication sharedApplication] openURL:url];
Of course you can use a format to include your own dynamic text, but the url string must be url escaped. Cocoa(Touch) provides a nice way to escape URLs, stringByAddingPercentEscapesUsingEncoding:
NSString *encodedBody = [eMailBody stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
The only problem left was representing tabular data. At first I though I’d use \t to create tabs, but I found out they’re not properly supported in e-mail bodies. Then a discussion on the Google Groups gave me the hint, the body parameter of mailto is actually parsed as HTML.
So, amazing as it seems, this code works:
NSString *eMailBody = @"<table>
<tr><td style='text-align:right'><b>Name</b>:</td>
<td>John</td></tr><tr>
<td style='text-align:right'><b>Surname</b>:</td><td>Doe</td></tr>
<tr><td style='text-align:right'>
<b>Occupation:<b/></td><td>Placeholder</td></tr></table>";
NSString *encodedBody =
[eMailBody stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *urlString =
[NSString stringWithFormat:@"mailto:me@me.com?subject=HiPhone&body=%@", encodedBody];
NSURL *url = [[NSURL alloc] initWithString:urlString];
[[UIApplication sharedApplication] openURL:url];
And here’s the result:
Bingo!
A weird downside of this method is that the user will be able to edit the email, but not is formatting: the bold characters will stay bold and so on; this seems to be a feature of the mail app itself.
Device vs Simulator
Since the iPhone simulator does not have a Mail.app, you can use e-mail URLs only in the actual device. As a matter of fact, it’s advisable to use compiler statements to create specific simulator/device code:
#if TARGETIPHONESIMULATOR
//compiler specific code
#else
// device specific code
#endif
In my app, I use a UIAlertView in the simulator code, so I can have the email text displayed onscreen. Currently I have a UITextView as its subview, but I plan to use a UIWebView, so I can preview the HTML in the simulator.
(Thanks to Slashzero for his comment)
Notes