How to add a UIImage in MailComposer Sheet of MFMailComposeViewController How to add a UIImage in MailComposer Sheet of MFMailComposeViewController ios ios

How to add a UIImage in MailComposer Sheet of MFMailComposeViewController


Back again with a new answer. I'm still leaving my previous code up though, because I'm still not convinced that there's not a way to make use of it. I'll keep at it myself. The following code DOES work. Mustafa suggests base64 encoding the images, and says that they only work Apple to Apple, but that's not actually true. Base64 encoding does work with most mail clients now (IE previously didn't support it, but now it is supported for images up to a certain size, though I'm not sure exactly what the size is). The problem is that mail clients like Gmail would strip out your image data, but there's a simple workaround for that... just putting <b> and </b> tags around your <img ...> tag is all you need to do to keep it from getting stripped out. In order to get an image into your email, you need to get a base64 encoder into your project. There are several out there (mostly C though), but the simplest ObjC one I found was called NSData+Base64 by Matt Gallagher (I took the "+" out of the name after copying it in because it gave me problems). Copy the .h and .m files into your project and be sure to #import the .h file where you plan on using it. Then code like this will get an image into your email body...

- (void)createEmail {//Create a string with HTML formatting for the email body    NSMutableString *emailBody = [[[NSMutableString alloc] initWithString:@"<html><body>"] retain]; //Add some text to it however you want    [emailBody appendString:@"<p>Some email body text can go here</p>"]; //Pick an image to insert //This example would come from the main bundle, but your source can be elsewhere    UIImage *emailImage = [UIImage imageNamed:@"myImageName.png"]; //Convert the image into data    NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(emailImage)]; //Create a base64 string representation of the data using NSData+Base64    NSString *base64String = [imageData base64EncodedString]; //Add the encoded string to the emailBody string //Don't forget the "<b>" tags are required, the "<p>" tags are optional    [emailBody appendString:[NSString stringWithFormat:@"<p><b><img src='data:image/png;base64,%@'></b></p>",base64String]]; //You could repeat here with more text or images, otherwise //close the HTML formatting    [emailBody appendString:@"</body></html>"];    NSLog(@"%@",emailBody); //Create the mail composer window    MFMailComposeViewController *emailDialog = [[MFMailComposeViewController alloc] init];    emailDialog.mailComposeDelegate = self;    [emailDialog setSubject:@"My Inline Image Document"];    [emailDialog setMessageBody:emailBody isHTML:YES];    [self presentModalViewController:emailDialog animated:YES];    [emailDialog release];    [emailBody release];}

I've tested this on the iPhone and sent lovely image embedded emails to myself on Yahoo, my personal website, and my MobileMe. I don't have a Gmail account, but the Yahoo worked perfectly, and every source I've found says that the bold-tags are all you need to make it work. Hope this helps all!


There are two ways to do this, depending on where the images are stored:

If the images are out on a server, then just include HTML <img> tags with the source URL set to the remote image. The user previewing the mail message is shown the image during composition and the receiver sees it when they open the message (unless they've disabled default image loading).

If the images are on the phone you could include them as 'inline' images. There are two steps to this. First you have to attach all the images you want to use as multi-part MIME attachments and they will need to be assigned a 'content ID' (aka cid), a filename, and Content-Disposition set to inline. Inside your HTML message body you can reference them like so:

<img src="cid:{messageid}/image.png" alt="My image" />

The bad news is, the standard iPhone mail composer mechanism doesn't allow adding this additional data to attachments. The second thing is to mark the email as having an "alternative" MIME content-type. Again, the mail composer doesn't let you do that.

The way around this is to either compose the message yourself then send it off to the mail server directly via SMTP, or have a server proxy do it for you via an SMTP relay. If you decide to go this way you might want to check out skpsmtpmessage on Google code or a service like AuthSMTP.

Once the user receives this message, however, they see a self-contained HTML message with all the inline images right there. But it's a lot of hassle to set up. The first method (putting images on server) is by far the easier way to go.


For iOS 3.0 and later, please see this: Attaching an image to an email?

Example:

UIImage * image = [UIImage imageWithContentsOfFile:imagePath];[composer addAttachmentData:UIImageJPEGRepresentation(itemImage, 1) mimeType:@"image/jpeg" fileName:@"MyFile.jpeg"];