I have implemented the module for sending the email from my iPhone device to server. When it comes to the implementation, there is no email file attach instead. I sweared I have added the attACHMENT . THE below is my working
-(IBAction)sendMail:(id)sender{
NSArray *toRecipents = [NSArray arrayWithObjects:#"birth.lo#sdsdfsfsdf-hk.com",#"jason.li#asdasdad-hk.com",#"lo.sdad#gmail.com",nil];
mailComposer = [[MFMailComposeViewController alloc]init];
if ([MFMailComposeViewController canSendMail]) {
mailComposer.mailComposeDelegate = self;
[mailComposer setSubject:#"NOXAV testing"];
[mailComposer setToRecipients:toRecipents] ;
[mailComposer setMessageBody:#"Testing message for the test mail" isHTML:NO];
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//make a file name to write the data to using the documents directory:
NSString *fileName = [NSString stringWithFormat:#"%#/textfile.txt",
documentsDirectory];
NSData *fileData = [NSData dataWithContentsOfFile:fileName];
NSString *mimeType = #"text/html";
[mailComposer addAttachmentData:fileData mimeType:mimeType fileName:fileName];
[self presentModalViewController:mailComposer animated:YES ];
}
}
-(void)mailComposeController:(MFMailComposeViewController *)controller
didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error{
if (result) {
NSLog(#"Result : %d",result);
}
if (error) {
NSLog(#"Error : %#",error);
}
[self dismissModalViewControllerAnimated:YES];
}
The MIME type for text file should be text/plain,So change
NSString *mimeType = #"text/html";
to
NSString *mimeType = #"text/plain";
Edit
Also change the fileName here
[mailComposer addAttachmentData:fileData mimeType:mimeType fileName:#"textfile.txt"];
Looks like file name problem, change following statement along with above suggested by Yogesh -
//make a file name to write the data to using the documents directory:
NSString * fileName = [documentsDirectory stringByAppendingPathComponent:#"textfile.txt"];
NSData *fileData = [NSData dataWithContentsOfFile:fileName];
NSString *mimeType = #"text/plain";
Your fileData may not be getting the data from file. Check if [filedata length] = some value.
Related
I am trying to attach a video to an email. It is not a local video so I write it to a file. Then I get the data from that file and attach to the email. When the email comes up, the only thing there is the file name "video.mp4" with no video.
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
NSData *videoData = [NSData dataWithContentsOfURL:url];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *tempPath = [documentsDirectory stringByAppendingFormat:#"/video.mp4"];
NSLog(#"writing");
BOOL success = [videoData writeToFile:tempPath atomically:NO];
if (success){
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfFile:tempPath];
NSLog(#"path: %#", tempPath);
if (error) {
NSLog(#"%#", [error localizedDescription]);
}else{
[controller addAttachmentData:data mimeType:#"video/mp4" fileName:#"video.mp4"];
NSLog(#"Data has loaded successfully.");
}
}
I think only approach to try is formatting mail as HTML. Otherwise you will always sending an attachment.
NSString *messageBody = #" /*Some HTML format containing HTML5 video player*/";
[controller setMessageBody:messageBody isHTML:YES];
So you need to look for suitable CSS and HTML tags for your video. But don't forget to test it with most e-mail clients as you may see different looks.
I am having issues getting my program to accept the path I gave it and returning it as NSData
// Get the resource path and read the file using NSData
NSString *searchFilename = #"SafetyAuditReport.pdf"; // name of the PDF you are searching for
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSDirectoryEnumerator *direnum = [[NSFileManager defaultManager] enumeratorAtPath:documentsDirectory];
NSString *documentsSubpath;
while (documentsSubpath = [direnum nextObject])
{
if (![documentsSubpath.lastPathComponent isEqual:searchFilename]) {
continue;
}
NSLog(#"found %#", documentsSubpath);
}
NSData *pdfData = [NSData dataWithContentsOfFile:documentsSubpath];
// Determine the MIME type
NSString *mimeType = #"application/pdf";
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:messageBody isHTML:NO];
[mc setToRecipients:toRecipents];
[mc addAttachmentData:pdfData mimeType:mimeType fileName:#""];
NSLog(#"data was loaded.......");
// Present mail view controller on screen
[self presentViewController:mc animated:YES completion:nil];
When ever the program gets the the emailing section it throws a nil exception for addAttachmentData:pdfData mimeType:mimeType fileName: saying the variable I gave it was nil (pdfData) when I know the file exists in the documents directory.
Thanks in advance
plz use this code
- (IBAction)sendMailWithAttachedFile
{
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
// NSURL* outputURL = [[NSURL alloc] initFileURLWithPath:[self pathForResourse:fileName ofType:extension]];
//Get the file path
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"data.pdf"];
NSURL* outputURL = [[NSURL alloc] initFileURLWithPath:path];
NSData *data=[[NSData alloc]initWithContentsOfURL:outputURL];
[picker addAttachmentData:data mimeType:#"application/pdf" fileName:#"data.pdf"];
[self presentModalViewController:picker animated:YES];
}
-(void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self dismissViewControllerAnimated:YES completion:nil];
}
Here is how we did it.....
NSString *path = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory,NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
path = [[NSBundle mainBundle]pathForResource:#"Name of File" ofType:#"pdf"];
NSData *pdfData = [NSData dataWithContentsOfFile:path];
MFMailComposeViewController *mail = [[MFMailComposeViewController alloc] init];
mail.editing = YES;
mail.mailComposeDelegate = self;
[mail setSubject:#"Your subject"];
[pdfData writeToFile:path atomically:NO];
[mail addAttachmentData:pdfData mimeType:#"application/pdf" fileName:#"Name OF File.pdf"];
[self presentViewController:mail animated:YES completion:NULL];
I'm writing a function to send a pdf file via email. On iOS I am encountering an issue where a pdf file gets generated and attached to an email and sent successfully, but the received email does not contain the original pdf file for some reason.
Here is my implementation using MFMailComposeViewController.
MFMailComposeViewController *mailer = [[[MFMailComposeViewController alloc] init] autorelease];
[mailer setMailComposeDelegate: id(m_delegate)];
[mailer setSubject:subject.toNSString()];
NSMutableArray *toRecipients = [[NSMutableArray alloc] init];
for(int i = 0; i < recipients.length(); i++)
{
[toRecipients addObject:recipients.at(i).toNSString()];
}
[mailer setToRecipients:toRecipients];
NSString *emailBody = body.toNSString();
[mailer setMessageBody:emailBody isHTML:NO];
// Determine the file name and extension
attachedFile = "/var/mobile/Containers/Data/Application/1DFBF012-4838-4350-B465-ECF247831EB3/Library/Application Support/test.pdf";
NSArray *filepart = [attachedFile.toNSString() componentsSeparatedByString:#"."];
NSString *filename = [filepart objectAtIndex:0];
NSString *extension = [filepart objectAtIndex:1];
// Get the resource path and read the file using NSData
NSString *filePath = [[NSBundle mainBundle] pathForResource:filename ofType:extension];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
// Determine the MIME type
NSString *mimeType;
if ([extension isEqualToString:#"jpg"]) {
mimeType = #"image/jpeg";
} else if ([extension isEqualToString:#"png"]) {
mimeType = #"image/png";
} else if ([extension isEqualToString:#"doc"]) {
mimeType = #"application/msword";
} else if ([extension isEqualToString:#"ppt"]) {
mimeType = #"application/vnd.ms-powerpoint";
} else if ([extension isEqualToString:#"html"]) {
mimeType = #"text/html";
} else if ([extension isEqualToString:#"pdf"]) {
mimeType = #"application/pdf";
}
// Add attachment
[mailer addAttachmentData:fileData mimeType:mimeType fileName:filename];
[qtController presentViewController:mailer animated:YES completion:nil];
I was able to see the file got attached to an email and sent it. I was able to receive the email sent. However, when I opened up the email it did not contain the file attached.
Any suggestion how I can troubleshoot this issue?
Here is my implementation of saving PDF file which follows standard file system path for saving application data.
/* Generate PDF file for sharing */
CGRect pageRect = CGRectMake(0, 0, 640, 480);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString * newFilePath = [documentPath stringByAppendingPathComponent:#"test.pdf"];
NSString *strFilename = newFilePath;
MyCreatePDFFile(pageRect, [strFilename UTF8String]);
I was looking for if there is a way to get the PDF file generated for trouble-shooting. It's located in Application Support directory which other application has no access to due to sand box policy. Quickest way is to enable file sharing for my app. And here is a helpful link teaches you how to enable file sharing for my app.
How to enable file sharing for my app?
So I pulled the PDF file from iPAD via iTune sharing from the app to my MAC. I was able to attached the same file and sent it via email on my MAC perfectly.
MFMailComposeViewController does not seem to complain the file but reject it silently. Is this considered a bug?
The bug was due to the attachment file path was not pointing to the pdf file wanted to be attached. Here is the fix for it:
// Get the resource path and read the file using NSData
NSString *filePath = newFilePath; // corrected the attachment file path
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
The follow implementation should run.
/* Generate PDF file for sharing */
CGRect pageRect = CGRectMake(0, 0, 640, 480);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString * newFilePath = [documentPath stringByAppendingPathComponent:#"test.pdf"];
NSString *strFilename = newFilePath;
MyCreatePDFFile(pageRect, [strFilename UTF8String]);
/* Attach PDF file generated */
NSString *emailTitle = #"Email PDF as attachment";
NSString *messageBody = #"Hey, check this out!";
NSArray *toRecipents = [NSArray arrayWithObject:#"grace#abc.com"];
//Implementation using MFMailComposeViewController
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:messageBody isHTML:NO];
[mc setToRecipients:toRecipents];
// Determine the file name and extension
NSArray *filepart = [strFilename componentsSeparatedByString:#"."];
NSString *filename = [filepart objectAtIndex:0];
NSString *extension = [filepart objectAtIndex:1];
// Get the resource path and read the file using NSData
NSString *filePath = newFilePath;
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
// Determine the MIME type
NSString *mimeType;
if ([extension isEqualToString:#"jpg"]) {
mimeType = #"image/jpeg";
} else if ([extension isEqualToString:#"png"]) {
mimeType = #"image/png";
} else if ([extension isEqualToString:#"doc"]) {
mimeType = #"application/msword";
} else if ([extension isEqualToString:#"ppt"]) {
mimeType = #"application/vnd.ms-powerpoint";
} else if ([extension isEqualToString:#"html"]) {
mimeType = #"text/html";
} else if ([extension isEqualToString:#"pdf"]) {
mimeType = #"application/pdf";
}
// Add attachment
[mc addAttachmentData:fileData mimeType:mimeType fileName:filename];
// Present mail view controller on screen
[self presentViewController:mc animated:YES completion:NULL];
Im trying to zip up my sqlite files from my documents directory to send via mail using https://github.com/mattconnolly/ZipArchive.
NSString *filePath = [[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"] stringByAppendingPathComponent:#"app.sqlite"];
NSString *filePath2 = [[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"] stringByAppendingPathComponent:#"app.sqlite-shm"];
NSString *filePath3 = [[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"] stringByAppendingPathComponent:#"app.sqlite-wal"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *archivePath = [documentsDirectory stringByAppendingString:#".zip"];
//Zip up files
ZipArchive *archiver = [[ZipArchive alloc] init];
[archiver CreateZipFile2:archivePath];
[archiver addFileToZip:filePath newname:#"backUp.sqlite"];
[archiver addFileToZip:filePath2 newname:#"backUp.sqlite-shm"];
[archiver addFileToZip:filePath3 newname:#"backUp.sqlite-wal"];
MFMailComposeViewController *mailView = [[MFMailComposeViewController alloc] init];
if (mailView != nil) {
mailView.mailComposeDelegate = self;
[mailView setSubject:#"Database"];
//Attach zip file
[mailView addAttachmentData:[NSData dataWithContentsOfFile:archivePath] mimeType:#"application/zip" fileName:#"test.zip"];
[mailView setMessageBody:#"Database attached" isHTML:NO];
[self presentViewController:mailView animated:YES completion: NULL];
}
The attachment appears in the email preview on the device but when it arrives with the recipient the attachment has vanished?
also tried this:
NSString *filePath = [[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"] stringByAppendingPathComponent:#"app.sqlite"];
NSString *filePath2 = [[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"] stringByAppendingPathComponent:#"app.sqlite-shm"];
NSString *filePath3 = [[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"] stringByAppendingPathComponent:#"app.sqlite-wal"];
DebugLog(#"DB path is: %#", filePath);
NSError *error = nil;
NSData *fileData = [[NSData alloc] initWithContentsOfFile:filePath options:0UL error:&error];
NSString* fileDataString = [[NSString alloc] initWithData:fileData encoding:NSNonLossyASCIIStringEncoding];
NSData *fileData2 = [[NSData alloc] initWithContentsOfFile:filePath2 options:0UL error:&error];
NSString* fileData2String = [[NSString alloc] initWithData:fileData2 encoding:NSNonLossyASCIIStringEncoding];
NSData *fileData3 = [[NSData alloc] initWithContentsOfFile:filePath3 options:0UL error:&error];
NSString* fileData3String = [[NSString alloc] initWithData:fileData3 encoding:NSNonLossyASCIIStringEncoding];
if (error != nil) {
DebugLog(#"Failed to read the file: %#", [error localizedDescription]);
} else {
if (fileData == nil) {
DebugLog(#"File data is nil");
}
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *archivePath = [documentsDirectory stringByAppendingString:#".zip"];
//Zip up documents directory
ZipArchive *archiver = [[ZipArchive alloc] init];
[archiver CreateZipFile2:archivePath];
[archiver addFileToZip:fileDataString newname:#"backUp.sqlite"];
[archiver addFileToZip:fileData2String newname:#"backUp.sqlite-shm"];
[archiver addFileToZip:fileData3String newname:#"backUp.sqlite-wal"];
MFMailComposeViewController *mailView = [[MFMailComposeViewController alloc] init];
if (mailView != nil) {
mailView.mailComposeDelegate = self;
[mailView setSubject:#"Database"];
//Attach zip file
[mailView addAttachmentData:[NSData dataWithContentsOfFile:archivePath] mimeType:#"application/zip" fileName:#"test.zip"];
[mailView setMessageBody:#"Database attached" isHTML:NO];
[self presentViewController:mailView animated:YES completion: NULL];
}
same behaviour zip file does not arrive with email
Logging the archivePath gives me /var/mobile/Containers/Data/Application/1D32A3AA-A431-46234-AE4B-ED944CA2D883F4/Documents.zip
Typically an email attachment doesn't arrive for one of two reasons:
The path you used to load the NSData resulted in the data being nil.
The file is too large to send via email.
You have several issues leading to problem one.
The path for the zip file is in a read-only folder - the root of your app's resource bundle.
Never use NSHomeDirectory() to create paths to folders in your app's sandbox. Things changed in iOS 8 and such paths won't work at all. Only use NSSearchPathForDirectoriesInDomains with the proper folder reference such as NSDocumentDirectory.
To solve the first issue, change this:
NSString *archivePath = [documentsDirectory stringByAppendingString:#".zip"];
to something like:
NSString *archivePath = [documentsDirectory stringByAppendingPathComponent:#"SomeFiles.zip"];
It would be even better to store this temporary file in the caches folder (use NSCachesDirectory instead of NSDocumentDirectory). Then delete the file after sending the email.
I can send a .csv file as an attachment from my app, but I'd like to shorten the name file for that attachment, because there will be a pile of csv files delivered to the recipient.
Piece of code:
...
if (dorsalesPorTramoYcontrol && dorsalesPorTramoYcontrol.count )
{
NSMutableString *mainString = [[ NSMutableString alloc]initWithString:#"dorsal,paso,tiempo\n"];
for (NSManagedObject *get in dorsalesPorTramoYcontrol) {
//dorsales
NSString *string =[get valueForKey:#"dorsal"];
[mainString appendFormat:#"%#,",string];
//paso
string = [get valueForKey:#"paso"];
string=[string stringByReplacingOccurrencesOfString:#"\"" withString:#"\"\""];
[mainString appendFormat:#"%#,",string];
//tiempo
string = [get valueForKey:#"tiempo"];
string=[string stringByReplacingOccurrencesOfString:#"\"" withString:#"\"\""];
[mainString appendFormat:#"%#",string];
[mainString appendFormat:#"\n"];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
file = [NSString stringWithFormat:#"%#/Tramo%#Control%#.csv", documentsDirectoryPath,section,control];
NSError *csVerror= NULL;
BOOL written = [mainString writeToFile:file atomically:YES encoding:NSUTF8StringEncoding error:&csVerror];
if (!written) {
NSLog( #"Writing failed, error = %#",csVerror);
}else {
NSLog(#"Data saved! File path = %#",file);
[self composeEmail];
}
}
}
-(void)composeEmail{
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:[NSString stringWithFormat:#"Resultados Tramo: %# - Control: %#", section, control]];
NSArray *toRecipients = [NSArray arrayWithObjects:#"somebodymail#mail.com", nil];
[mailer setToRecipients:toRecipients];
// Logo
UIImage *myImage = [UIImage imageNamed:#"logo.png"];
NSData *imageData = UIImagePNGRepresentation(myImage);
[mailer addAttachmentData:imageData mimeType:#"image/png" fileName:#"Icon"];
[mailer addAttachmentData:[NSData dataWithContentsOfFile:file] mimeType:#"text/csv" fileName:file];
NSString *emailBody =
[NSString stringWithFormat:#"Resultados Tramo: %# - Control: %# \nDorsal - Paso - Tiempo", section, control];
[mailer setMessageBody:emailBody isHTML:NO];
mailer.modalPresentationStyle = UIModalPresentationPageSheet;
[self presentViewController:mailer animated:YES completion:nil];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Failure"
message:#"Your device doesn't support the composer sheet"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
}
}
The filename is the following:
<_var_mobile_Applications_BE8CE610-A83E-4C79-8B9C-0263FA6881D6_Documents_Tramo2Control4.csv>
and I'd like it to be just "Tramo2Control4.csv"
Could you please offer some suggestions to get it?
Change the following line:
[mailer addAttachmentData:[NSData dataWithContentsOfFile:file] mimeType:#"text/csv" fileName:file];
To:
NSString *fileName = [file lastPathComponent];
[mailer addAttachmentData:[NSData dataWithContentsOfFile:file] mimeType:#"text/csv" fileName:fileName];
You were originally setting the file name to be the entire file path.