NSString losing new lines when added to mail body - iphone

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];

Related

MFMailComposeViewController image attachment and HTML body

Hopefully simple question:
Is there a way to attach an image to the MFmailcomposeviewcontroller AND have an HTML formatted body? Everytime I try, I can do one or the other, but not both. If I set isHTML:YES, it gives me the HTML body format, but then it embeds my image attachment (not what I want). If I do isHTML:NO, the image is attached as a file (what I want) but the body message obviously won't respect my br line breaks.
Any suggestions?
-(IBAction)clickSend:(id)sender{
MFMailComposeViewController *mailComposer=[[MFMailComposeViewController alloc]init];
mailComposer.mailComposeDelegate=self;
NSString *bodyString=[self MessageBody];
[mailComposer setMessageBody:bodyString isHTML:YES];
[self presentViewController:mailComposer animated:YES completion:nil];
}
-(NSMutableString *)MessageBody{
NSMutableString *bodyString=[[NSMutableString alloc]initWithString:#"<html><body>"];
[bodyString appendString:#"<p>Sending Email with Image</p>"];
[bodyString appendString:#"<div style=\"background:url(http://t3.gstatic.com/images?q=tbn:ANd9GcQVd7uDWzEt7J4jimllpd9oTNBsQn-GFWUYIeGoiK_4-o4tPYGz); height:280px; width:510px; margin:60px 5px;\">"];
[bodyString appendString:#"</div> </body> </html>"];
return bodyString;
}
Hope, this will help you

UIPasteboard copy fails to paste correctly in Notes and Mail

I'm using the following code to copy a string of text which contains both English and Hebrew characters into UIPasteboard.
UIPasteboard *appPasteBoard = [UIPasteboard generalPasteboard];
appPasteBoard.persistent = YES;
NSString *toCopy = [self.workingDvarTorah description];
[appPasteBoard setValue:toCopy forPasteboardType:(NSString *)kUTTypeUTF8PlainText];
I've implemented my own version of the description method, to copy the relevant data, here's that:
- (NSString *)description{
// Build a string from the tags
NSMutableString *tags = [[[NSMutableString alloc] init] autorelease];
BOOL isFirstTag = YES;
for (Tag *aTag in self.tags) {
// Add a comma where necessary, but make
// sure that we're not adding a comma to
// the beginning of the first tag.
if (isFirstTag) {
isFirstTag = NO;
[tags appendFormat:#" "];
}else{
[tags appendFormat:#", "];
}
[tags appendFormat:#"%#", aTag.tagText];
}
return [NSString stringWithFormat:#"%# \n\n %#\n\n%#: %#", self.dvarTorahTitle, self.dvarTorahContent, NSLocalizedString(#"Tags", #""), tags];
}
The text copies to the pasteboard, but when I paste it into notes or mail, certain characters, nameley the dagesh, unicode character 05BC, appears as a box, instead of the way it should. I've tried all of the text UTI types.
Am I doing something wrong? Is this a bug in iOS or the Notes app?
What can I do, short of stripping the offending characters, to correct the problem?
According to Wikipedia, there are two representations of Hebrew characters with dagesh in them. Apparently, there is a "combined character" and an alternate representation composed of two alternate characters. The program which created my initial data file may have used the combined character. When the data was exported again without the combined characters, the copy-paste worked.
So, it looks like there are certain characters that are unsupported by Notes and Mail for iOS.

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

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

adding new line to html body in mailcomposer

How do i add a new line characters to html body of mail composer?
I have a string:
NSString *emailBody = [NSString stringWithFormat:#"<html><b>%%0D%%0AHello,%%0D%%0AHere's a link to your product%%0D%%0Aclick here%%0D%%0A best regards</b></html>", currentProduct.url_product_details];
[picker setMessageBody:emailBody isHTML:YES];
When I set the body of a mail composer I see it without new lines.
How do i cause new lines to appear?
TIA
In HTML, newlines are <br />, not %0D%0A.
And use <p>...</p> for a paragraph.
For example,
NSString* emailBody = [NSString stringWithFormat:
#"<html><head></head><body style='font-weight:bold;'>"
#"<p>Hello,</p>"
#"<p>Here's a link to your product<br /><a href='%#'>click here</a></p>"
#"<p>Best Regards</p>"
#"</body></html>", currentProduct.url_product_details];

Encoding spaces in UITextView / UITextField to URL format

I'm trying to send the contents of UITextView or UITextField as parameters to a php file
NSString *urlstr = [[NSString alloc] initWithFormat:#"http://server.com/file.php?name=%#&tags=%#&entry=%#",nameField.text, tagsField.text, dreamEntry.text];
When i log urlstr, the url format is ok just as long as the UITextView or UITextField don't contain spaces. How would i go about converting the spaces to %20 ?
edit
here is the code at present, which not only crashes but isn't encoding the url properly.
name=John Doe&tags=recurring nightmare&entry=Testing testing testing
is converted to
name=John -1844684964oe&tags=recurringightmare&entry=Testing 4.214929e-307sting -1.992836e+00sting
- (IBAction)sendButtonPressed:(id)sender
{
NSString *urlString = [[NSString alloc] initWithFormat:#"http://server.com/file.php?name=%#&tags=%#&entry=%#", nameField.text, tagsField.text, dreamEntry.text];
NSString *encodedString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [[NSURL alloc] initWithString:encodedString];
NSLog(encodedString);
NSLog(urlString);
[urlString release];
[url release];
[encodedString release];
}
Actually, all of the previous answers contain at least some inaccuracies, which for many common values of user provided text in the TextFields would not correctly communicate with the server
stringByAddingPercentEscapesUsingEncoding: percent escapes all characters which are not valid URL characters. This method should applied once to the entire URL.
A previous answer claims that stringByAddingPercentEscapesUsingEncoding: works like the URL building classes in many scripting languages, where you should not apply it to the entire URL string, but it doesn't. Anyone can easily verify this by checking its output for unescaped &s and ?s. So it is fine to apply to the entire string, but it is not enough to apply to your 'dynamic' url content.
The previous answer is right in that you have to do some more work to the names and values that go into your CGI query string. Since CGI is specified by RFC3875, this is often referred to as RFC3875 percent escaping. It makes sure that your names and values don't contain characters that are valid URL characters but which are significant in other parts of the URL (;, ?, :, #, &, =, $, +, {, }, <, >, and ,)
However, it is very important to also finish by doing plain URL percent escapes on the full string to make sure that all characters in the string are valid URL characters. While you don't in your example, in general there could be characters in a 'static' part of the string which are not valid URL characters, so you do need to escape those as well.
Unfortunately, NSString doesn't give us the power to escape the RFC3875 significant characters so we have to dip down into CFString to do so. Obviously using CFString is a pain so I generally add a Category onto NSString like so:
#interface NSString (RFC3875)
- (NSString *)stringByAddingRFC3875PercentEscapesUsingEncoding:(NSStringEncoding)encoding;
#end
#implementation NSString (RFC3875)
- (NSString *)stringByAddingRFC3875PercentEscapesUsingEncoding:(NSStringEncoding)encoding {
CFStringEncoding cfEncoding = CFStringConvertNSStringEncodingToEncoding(encoding);
NSString *rfcEscaped = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)self,
NULL,
(CFStringRef)#";/?:#&=$+{}<>,",
cfEncoding);
return [rfcEscaped autorelease];
}
#end
With this Category in place, the original problem could be correctly solved with the following:
NSString *urlEscapedBase = [#"http://server.com/file.php" stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding];
NSString *rfcEscapedName = [nameField.text stringByAddingRFC3875PercentEscapesUsingEncoding:
NSUTF8StringEncoding];
NSString *rfcEscapedTags = [tagsField.text stringByAddingRFC3875PercentEscapesUsingEncoding:
NSUTF8StringEncoding];
NSString *rfcEscapedEntry = [dreamEntry.text stringByAddingRFC3875PercentEscapesUsingEncoding:
NSUTF8StringEncoding];
NSString *urlStr = [NSString stringWithFormat:#"%#?name=%#&tags=%#&entry=%#",
urlEscapedBase,
rfcEscapedName,
rfcEscapedTags,
rfcEscapedEntry];
NSURL *url = [NSURL URLWithString:urlStr];
This is a little variable heavy just be more clear. Also note that the variable list provided to stringWithFormat: should not be nil terminated. The format string describes the precise number of variables that should follow it. Also, technically the strings for query string names (name, tags, entry,..) should be run through stringByAddingPercentEscapesUsingEncoding: as a matter of course but in this small example we can easily see that they contain no invalid URL characters.
To see why the previous solutions are incorrect, imagine that the user input text in dreamEntry.text contains an &, which is not unlikely. With the previous solutions, all text following that character would be lost by the time the server got that text, since the unescaped ampersand would be interpreted by the server as ending the value portion of that query string pair.
You're not supposed to URL-escape the entire string, you're supposed to URL-escape the dynamic components. Try
NSString *urlStr = [NSString stringWithFormat:#"http://server.com/file.php?name=%#&tags=%#&entry=%#",
[nameField.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[tagsField.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[dreamEntry.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
nil];
NSURL *url = [NSURL URLWithString:urlStr];
The second issue with your code (and undoubtedly the reason for the odd printing) is you're passing the string directly to NSLog, so it's being treated as a format string. You need to use
NSLog(#"%#", encodedString);
instead. That will make it print as expected.
Edit: A third issue with your code is you're mixing autoreleased and owned objects, then releasing them all at the end. Go look at the 3 objects you create, and which you subsequently release later. One of them shouldn't be released later because it was produced by a method that did not start with the words alloc, copy, or new. Identifying the object in question is an exercise left to the reader.
You can take your URL and use:
NSString *urlStr = [[NSString alloc] initWithFormat:#"http://server.com/file.php?name=%#&tags=%#&entry=%#",nameField.text, tagsField.text, dreamEntry.text];
NSString *encStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];