Emailing HTML from within an iPhone app is stopping at special characters - iphone

I have an iPhone app that will let users email some pre-determined text as HTML.
I'm having a problem in that if the text contains special characters within the text (e.g., ampersand &, >, <), the NSString variable that I use for sending the body of the email gets truncated at the special character.
I'm not sure how to fix this (I tried using the method stringByAddingPercentEscapesUsingEncoding…but this hasn't fixed the problems).
Thoughts on what I'm doing wrong / how to fix it?
Here is sample code showing what I'm trying to do
Thanks!!!
- (void)send_an_email:(id)sender {
NSString *subject_string = [NSString stringWithFormat:#"Summary of %#", commercial_name];
NSString *body_string = [NSString stringWithFormat:#"%#<br /><br />", [self.dl email_message]]; // email_message returns the body of text that should be shipped as html. If email_message contains special characters, the text truncates at the special character
NSString *full_string = [NSString stringWithFormat:#"mailto:?to=&subject=%#&body=%#", [subject_string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], [body_string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:[[NSURL alloc] initWithString:full_string]];
}

This works for me to send email from within the app. The way you have it, it quits the app and opens Mail. Try something like this:
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
... do your email setup code
[picker setMessageBody:emailBody isHTML:YES];
Here is a good tutorial

Related

calling phone number within the app issue

I have the following code:
phoneNumber = (NSString*)CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones, i));
NSString *phoneNumberURLString = [[NSString alloc] initWithFormat:#"tel://%#", phoneNumber];
NSURL *phoneURL = [[NSURL alloc] initWithString:phoneNumberURLString];
[[UIApplication sharedApplication] openURL:phoneURL];
However, the issue with this is that, sometimes a certain phone number doesn't get called: for example if phoneNumber is (520) 123-1232, then this doesn't call the phone. Any idea on how to standarize the phone number format such that this method works for all cases?
It is the spaces in the number. A space is not a valid URL character. It must be encoded propery as %20.

NSString losing new lines when added to mail body

I am storing some text as an NSString. The text contains multiple paragraphs. When I log or display the text the new line characters are inserted correctly.
However, when I use the MFMailComposeViewController and add the text to the mail's body, the new lines are removed and the text runs together.
What is causing this, and how do I preserve the formatting?
I believe the way you're doing this should be working, if by line break you're referring to \n. One alternative would be to replace the occurrences of \n with <br> and set the composer's isHTML flag to YES:
NSString *emailString = [myParagraphs stringByReplacingOccurrencesOfString:#"\n" withString:#"<br>"];
[mailComposer setMessageBody:emailString isHTML:YES];
(OK, if everyone writes an answer from my comment, then I write one too...)
If you instruct the view controller to treat the text as HTML, you can preserve its formatting, else it'll be discarded. Note that in this case you'll have to feed it actual HTML, of course (\n in HTML isn't any good). So try:
NSCharacterSet *set = [NSCharacterSet newlineCharacterSet];
NSString *html = [[body componentsSeparatedByCharactersInSet:set]
componentsJoinedByString:#"<br />"];
[viewController setMessageBody:html isHTML:YES];
As mentioned by H2CO3 in comments, you need to wrap it as HTML content.
NSString *myEmailBody = #"First Line <br/> Second <br/> Third";
[composer setMessageBody:myEmailBody isHTML:YES];

Base64 HTML embedded images not showing when mailed

I am embedding images that have been base64 encoded in HTML as follows:
[html appendFormat:#"<html><body><p><b><img src=\"data:image/png;base64,%#\"></b></p></body><html>", base64ImageString];
I then create a new email as follows:
MFMailComposeViewController *mailVC = [[MFMailComposeViewController alloc] init];
mailVC.mailComposeDelegate = self;
[mailVC setMessageBody:html isHTML:YES];
[self presentModalViewController:mailVC animated:YES];
The embedded image does show up in the new email before it is sent, but is not displayed in any email client to which the mail is delivered. I would think the fact that the image properly shows in the draft shows that the embedding process is successful, but I dont understand why it does not show when delivered. Looking at the raw HTML in the delivered mail shows: src="cid:(null)" Any help would be appreciated please!
I stumbled into this same problem and the solution was rather convoluted. It is possible to embed an image in an email. The problem is that for some weird reason the base64 encoded image must not contain new lines (super odd! I know). I'm guessing you are using the NSData+Base64 by Matt Gallagher? So was I! This category creates a multi-line base64 string. The code in the category is
- (NSString *)base64EncodedString
{
size_t outputLength;
char *outputBuffer =
NewBase64Encode([self bytes], [self length], true, &outputLength);
NSString *result =
[[NSString alloc]
initWithBytes:outputBuffer
length:outputLength
encoding:NSASCIIStringEncoding];
free(outputBuffer);
return result;
}
By replacing the third parameter of NewBase64Encode to false you will get a single line base64 string and that worked for me. I ended up creating a new function (just not to break anything else!) within the category.
- (NSString *)base64EncodedStringSingleLine
{
size_t outputLength;
char *outputBuffer =
NewBase64Encode([self bytes], [self length], false, &outputLength);
NSString *result =
[[NSString alloc]
initWithBytes:outputBuffer
length:outputLength
encoding:NSASCIIStringEncoding];
free(outputBuffer);
return result;
}
Using this function to encode the UIImage's NSData worked fine. The email clients I have tested so far all show the embedded image. Hope it works for you!
Edit: As pointed out in the comments, this solution is only partial. The image will be attached as a Data URI in the email. However, not all email clients will display the embedded image.

iPhone: attaching an image from image picker to email does not display on windows

[SOLVED] Guess I should have RTFM! Using [MFMailComposeViewController addAttachmentData: mimeType: fileName:] solved my problem completely. No need for base64 encoding at all :)
For anyone whose interested this question provides some good information about base64 encoding.
I allow the user to take or choose an image and attach it to an email. The email sends and delivers perfectly well in Mac Mail but on Windows (Outlook Express & gmail) the image does not display. Gmail tells me 'The Conversion Cannot Be Loaded'.
Below is the code I use to attach the image to an email. It must eb something to do with the encoding of the image. Can anyone advise?
Many thanks for any help
- (void) createEmail {
// set up the image data.
NSData *imageData = [NSData dataWithData:UIImageJPEGRepresentation(self.imageToUpload, 1.0)];
NSString *base64String = [imageData base64EncodedString];
NSString *emailBodyString = [NSString stringWithFormat:#"<html><body><img src='data:image/jpeg;base64,%#'></body></html>",base64String];
// create the email modal
NSArray *recipients = [[NSArray alloc] initWithObjects:#"test#email.com",nil];
MFMailComposeViewController *emailDialog = [[MFMailComposeViewController alloc] init];
emailDialog.mailComposeDelegate = self;
[emailDialog setToRecipients:recipients];
[emailDialog setSubject:#"Time Sheet Submission from iPhone App"];
[emailDialog setMessageBody:emailBodyString isHTML:YES];
[self presentModalViewController:emailDialog animated:YES];
[emailDialog release];
[recipients release];
}
Guess I should have RTFM! Using [MFMailComposeViewController addAttachmentData: mimeType: fileName:] solved my problem completely. No need for base64 encoding at all :)
For anyone whose interested this question provides some good information about base64 encoding.

Why MFMailComposer with <img> is not showing the image in mail?

I am sending some images in mail using MFMailComposer. I am converting the image to Base64 and using <img> tag to add images to the HTML body(I am not adding it as attachment).
[htmlString appendFormat:
#"<img src='data:image/png;base64,%#' width=300 height=200 />", imageAsBase64];
The images are displaying correctly in MFMailComposer, but there are no images displayed in the actual mail which is sent from the MFMailComposer.
What should I do to make it work?
I had same problem before couple of weeks and I came to know that Gmail is not supporting embedded images. You can see images in email in other mail provider like your domain email but not in Gmail.
Try to send another email and you can see images. You need to add images as attachment then you can see images and it will display bottom of your email body.
Hope this help.
You have to add the images as an attachment. The rendered email that you see with HTML doesn't get rendered properly with the missing image URL.
here is an example: the caveat is that if you want to include things like a PDF you must include an image otherwise mfmailcomposer will fail... this in an apple bug.
I found the solution... Isubmitted a bug on Apple radar about it. MFMailcomposer has a bug in which you have to send an image along with your extra attachments in order to get the weird items like a pdf to work... try this and replace the pdf with your card:
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
NSString *emailSubject = [NSString localizedStringWithFormat:#"MedicalProfile"];
[controller setSubject:emailSubject];
NSString *fileName = [NSString stringWithFormat:#"%#.pdf", profileName];
NSString *saveDirectory = NSTemporaryDirectory();
NSString *saveFileName = fileName;
NSString *documentPath = [saveDirectory stringByAppendingPathComponent:saveFileName];
*** YOU MUST INCLUDE AN IMAGE OR THE PDF ATTATCHMENT WILL FAIL!!!***
// Attach a PDF file to the email
NSData *pdfData = [NSData dataWithContentsOfFile:documentPath];
[controller addAttachmentData:pdfData mimeType:#"application/pdf" fileName:fileName];
// Attach an image to the email
NSString *imagePath = [[NSBundle mainBundle] pathForResource:#"miniDoc" ofType:#"png"];
NSData *imageData = [NSData dataWithContentsOfFile:imagePath];
[controller addAttachmentData:imageData mimeType:#"image/png" fileName:#"doctor"];
[controller setMessageBody:[NSString stringWithFormat:#"%#'s Medical Profile attatched!", profileName] isHTML:NO];
[self presentModalViewController:controller animated:YES];
controller.mailComposeDelegate = self;
[controller release];