MFMailComposeViewController csv attachment not being attached, but showing inline instead - csv

I am having a problem with sending csv attachments via MFMailComposeViewController.
Sometimes they come through just fine, but for other users they don't come through as attachments, but rather as text inline in the email (with <br/> instead of line returns.) It's very strange. Anybody know what I'm doing wrong?
Here is a snippet of my code:
MFMailComposeViewController *mailComposeViewController = [[MFMailComposeViewController alloc] init];
mailComposeViewController.mailComposeDelegate = self;
NSString *csv = #"foo,bar,blah,hello";
NSData *csvData = [csv dataUsingEncoding:NSUTF8StringEncoding];
[mailComposeViewController addAttachmentData:csvData mimeType:#"text/csv" fileName:#"testing.csv"];
[mailComposeViewController setSubject:#"testing sending csv attachment"];
[mailComposeViewController setMessageBody:#"csv file should be attached" isHTML:NO];
[self presentModalViewController:mailComposeViewController animated:YES];

-(IBAction)btnPressed:(id)sender {
NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *docDir = [arrayPaths objectAtIndex:0];
NSString *Path = [docDir stringByAppendingString:#"/CSVFile.csv"];
NSData *csvData = [NSData dataWithContentsOfFile:Path];
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:#"For csv file..."];
[controller setMessageBody:#"...csv file is hear.." isHTML:NO];
[controller addAttachmentData:csvData mimeType:#"text/csv" fileName:#"CSVFile.csv"];
[self presentModalViewController:controller animated:YES];
[controller release];
}

Hi I put sample code for Creating CSV file and attach it with mail but make sure you have to add MessageUI.Framework and import its related header "MessageUI/MessageUI.h"
"MessageUI/MFMailComposeViewController.h" and deligate "MFMailComposeViewControllerDelegate"...I hope this wl useful for others
- (void)viewDidLoad {
arrCsv=[[NSArray alloc]initWithObjects:#"Hello",#"Hi",#"traun",#"fine",nil];
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileName = [NSString stringWithFormat:#"%#/try.csv", documentsDirectory];
[[arrCsv componentsJoinedByString:#","] writeToFile:fileName atomically:YES encoding:NSUTF8StringEncoding error:NULL];
}
-(ibAction)btnMail {
NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *docDir = [arrayPaths objectAtIndex:0];
NSString *Path = [docDir stringByAppendingString:#"/CSVFile.csv"];
NSData *csvData = [NSData dataWithContentsOfFile:Path];
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:#"For csv file..."];
[controller setMessageBody:#"...csv file is hear.." isHTML:NO];
[controller addAttachmentData:csvData mimeType:#"text/csv" fileName:#"CSVFile.csv"];
[self presentModalViewController:controller animated:YES];
[controller release];
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{ message.hidden = NO;
switch (result)
{
case MFMailComposeResultCancelled:
message.text = #"Result: canceled";
break;
case MFMailComposeResultSaved:
message.text = #"Result: saved";
break;
case MFMailComposeResultSent:
message.text = #"Result: sent";
break;
case MFMailComposeResultFailed:
message.text = #"Result: failed";
break;
default:
message.text = #"Result: not sent";
break;
}
[self dismissModalViewControllerAnimated:YES];
}

set the mime type as "application/octet-stream" and that should do the trick to remove inline attachments (I still named the extension of my file i.e. pdf)

I believe the second parameter to setMessageBody:isHTML: must be YES for attachments to not show up inline.

Even if you set isHTML param to YES, your message body can be sent as plain/text if the message body can be represented as such. And attachments in plain/text messages are not always recognized correctly by some email clients (Outlook).
In my case adding a link in the message body helped. Formatting text as bold with HTML tags works too. Tricky!
Tested on iPod 1G 3.1.3.

This may not be the case here, but one thing to watch out for is that:
[NSString dataUsingEncoding:]
returns a valid but empty NSData object if the conversion to the specified encoding is not possible. Better to use the full version:
[NSString dataUsingEncoding: s allowLossyConversion: YES]
Or check the length of the returned data. It appears that zero-length data attachments are trimmed somewhere in the mail process.

Related

NSString remove html tags, keep <Text in angle brackets>

How do I remove html tags from NSString, but keep any <Text in angle brackets>?
Like <p>123 <Hello> abc</p> -> 123 <Hello> abc
I have tried all kinds of regexp, scanner and XML Parser solutions, but they remove <Text in angle brackets> as well as tags.
The only solution that fit me was to use an NSAttributedString with options
NSAttributedString *str = [[NSAttributedString alloc] initWithData:utf8Data
options:#{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: #(NSUTF8StringEncoding)}
documentAttributes:nil
error:nil];
NSString *result = [str string];
but this approach employs WebKit and consumes too much memory for my task.
So, how do I strip tags from NSString, keeping <Text in angle brackets> without using any kind of WebKit/UIWebView and so on?
I asked a similar questionma while ago, may be some of the answers can help you out.
If you do need the full HTML parser and just want to strip HTML tags out, a NSString category might be useful (this one is a modified category by mwaterfal):
- (NSString *)stringByStrippingTags {
// Find first & and short-cut if we can
NSUInteger ampIndex = [self rangeOfString:#"<" options:NSLiteralSearch].location;
if (ampIndex == NSNotFound) {
return [NSString stringWithString:self]; // return copy of string as no tags found
}
// Scan and find all tags
NSScanner *scanner = [NSScanner scannerWithString:self];
[scanner setCharactersToBeSkipped:nil];
NSMutableSet *tags = [[NSMutableSet alloc] init];
NSString *tag;
do {
// Scan up to <
tag = nil;
[scanner scanUpToString:#"<" intoString:NULL];
[scanner scanUpToString:#">" intoString:&tag];
if (tag) {
NSString *t = [[NSString alloc] initWithFormat:#"%#>", tag];
[tags addObject:t];
}
} while (![scanner isAtEnd]);
NSMutableString *result = [[NSMutableString alloc] initWithString:self];
NSString *finalString;
NSString *replacement;
for (NSString *t in tags) {
replacement = #" ";
if ([t isEqualToString:#"<a>"] ||
[t isEqualToString:#"</a>"] ||
[t isEqualToString:#"<span>"] ||
[t isEqualToString:#"</span>"] ||
[t isEqualToString:#"<strong>"] ||
[t isEqualToString:#"</strong>"] ||
[t isEqualToString:#"<em>"] ||
[t isEqualToString:#"</em>"]) {
replacement = #"";
}
[result replaceOccurrencesOfString:t
withString:replacement
options:NSLiteralSearch
range:NSMakeRange(0, result.length)];
}
// Remove multi-spaces and line breaks
return = [result stringByRemovingNewLinesAndWhitespace];
}

Sending base64 UIImages comes out empty

I'm trying to send an HTML email with embedded UIImages.
This is my code:
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
[mailComposer setSubject:NSLocalizedString(#"Subject", #"Default Subject")];
// Build email body (HTML)
UIImage *emailImage = [UIImage imageNamed:#"image.png"];
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(emailImage)];
NSString *base64String = [imageData base64EncodedString];
NSMutableString *emailBody = [[NSMutableString alloc] initWithString:#"<HTML>Hey,<br><br>Here's the image!"];
[emailBody appendString:[NSString stringWithFormat:#"<img src='data:image/png;base64,%#'></html>",base64String]];
[mailComposer setMessageBody:emailBody isHTML:YES];
[delegate.viewController presentModalViewController:mailComposer animated:YES];
When the Email Modal View Controller comes up I see the images just fine. But when I tried to view this email on my Mac and on my iPhone and the images comes out empty.

How to encode odd HTML characters with Xcode?

I need to save a HTML page in my app, and when characters like "€" are found, the saved file displays them wrong.
I tried several encodings but none solves this, is there any solution?
I have also tried to replace the characters for the HTML name, but it still doesn't work.
Here's my code:
NSString *HTML = [web stringByEvaluatingJavaScriptFromString:#"document.getElementsByTagName('html')[0].innerHTML;"];
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [NSString stringWithFormat:#"%#/%#", [path objectAtIndex:0],#"code.html"];
int enc_arr[] = {
NSISOLatin1StringEncoding, // ESP
NSUTF8StringEncoding, // UTF-8
NSShiftJISStringEncoding, // Shift_JIS
NSJapaneseEUCStringEncoding, // EUC-JP
NSISO2022JPStringEncoding, // JIS
NSASCIIStringEncoding // ASCII
};
NSData *urlData= nil;
for (int i=0; i<6; i++) {
urlData = [HTML dataUsingEncoding:enc_arr[i]];
if (urlData!=nil) {
break;
}
}
[urlData writeToFile:filePath atomically:YES];
See these methods of NSString:
- (NSStringEncoding)smallestEncoding
- (NSStringEncoding)fastestEncoding
or just use method below with flag set to YES :
- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding allowLossyConversion:(BOOL)flag
but with this one you can loose some characters.
Ok I finally did it, it's not the best way but the only one that worked for me and without using external libraries:
-(NSString*)escapeHTML:(NSString*)code{
NSMutableArray *maExceptions = [[NSMutableArray alloc] initWithObjects: #"Œ", #"œ", #"Š", #"š", #"Ÿ", #"ƒ", #"‘", #"’", #"‚", #"“", #"”", #"„", #"†", #"‡", #"•", #"…", #"‰", #"€", #"™", nil];
for (int i=0; i<[maExceptions count]; i++) {
code = [code stringByReplacingOccurrencesOfString:[maExceptions objectAtIndex:i] withString:[NSString stringWithFormat:#"&#x%x;",[[maExceptions objectAtIndex:i] characterAtIndex:0]]];
}
return code;
}

DTAttributedTextCell with clickable link

I'm trying to reuse DTAttributedTextCell with clickable link. I could get hold of the attributedstring but I'm not sure how i can get the frame for the text such that I can create a DTLinkButton.
Here's the sample code from the Demoapp:
- (void)configureCell:(DTAttributedTextCell *)cell forIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *snippet = [_snippets objectAtIndex:indexPath.row];
NSString *title = [snippet objectForKey:#"Title"];
NSString *description = [snippet objectForKey:#"Description"];
NSString *html = [NSString stringWithFormat:#"<h3>%#</h3><p>%#</font>Test</p>", title, description];
[cell setHTMLString:html];
cell.attributedTextContextView.shouldDrawImages = YES;
}
Any pointers will be awesome.

Searching for keywords in HTML

The iOS app I'm writing displays an HTML page, and I would like to add a search feature where the user can search for instances of a keyword and highlight them.
What's the best way to do this?
NSString *filePath = PATH_OF_HTML_FILE;
NSError *err = nil;
NSString *pageHTML = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&err];
if(err)
{
pageHTML = [NSString stringWithContentsOfFile:filePath encoding:NSASCIIStringEncoding error:&err];
}
if([searchTxtField.text length])
{
NSRange range1 = [pageHTML rangeOfString:searchTxtField.text options:NSCaseInsensitiveSearch];
if(range1.location != NSNotFound)
{
NSString *highlightedString = [pageHTML substringWithRange:range1];
pageHTML = [pageHTML stringByReplacingOccurrencesOfString:highlightedString withString:[NSString stringWithFormat:#"<span style=\"background-color:yellow; color:red;\">%#</span>",highlightedString] options:NSCaseInsensitiveSearch range:NSMakeRange(0, [pageHTML length]) ];
[webView loadHTMLString:pageHTML baseURL:[NSURL fileURLWithPath:filePath]];
}
}