I am trying to attach a docx file when sending email but I am having trouble. These 2 lines are always nil. The variables filename and extension are not nil but file comes up as nil. Not sure if this matters but the docx file is dynamically generated, what if I were to use the NSData from the generated file instead of creating a new NSData variable here?
filepath = /Users/myself/components/file.docx
NSString *file = [[NSBundle mainBundle] pathForResource:filename ofType:extension];
NSData *fileData
= [NSData dataWithContentsOfFile:file];
here is the code
-(void)sendEmail:(NSString*)filePath{
if ([MFMailComposeViewController canSendMail])
{
mailComposer = [[MFMailComposeViewController alloc]init];
mailComposer.mailComposeDelegate = self;
[mailComposer setToRecipients:#[#"name#gmail.com"]];
[mailComposer setSubject:#"Mobile File Attachment"];
[mailComposer setMessageBody:#"DocX file attached" isHTML:NO];
// Determine the file name and extension
if(![filePath isEqual:nil])
{
NSArray *filepart = [filePath componentsSeparatedByString:#"."];
NSString *filename = [filepart objectAtIndex:0];
NSString *extension = [filepart objectAtIndex:1];
// Get the resource path and read the file using NSData
NSString *file = [[NSBundle mainBundle] pathForResource:filename ofType:extension];
NSData *fileData = [NSData dataWithContentsOfFile:file];
// 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:#"docx"]) {
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
[mailComposer addAttachmentData:fileData mimeType:mimeType fileName:filename];
}
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:mailComposer animated:YES completion:nil];
}
EDIT: add value of filePath and this is how I generate the file
NSAttributedString *str = [[NSAttributedString alloc] initWithAttributedString:_textV.attributedText];
//convert to html then write to a .docx file to export to docx
NSData *data = [str dataFromRange:(NSRange){0, [str length]} documentAttributes:#{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType} error:NULL];
[data writeToFile:#"/Users/myself/components/file.docx" atomically:YES];
The issue here as you've mentioned is those two lines - if the file is dynamically generated, it won't be in the main bundle - that's the bundle of an application (each app on OS X and iOS is a folder /"bundle" or "package"/, which contains other files. Using this method, you are retrieving files that are packaged with the app.
If you are generating the content, you are likely writing it to a different path (temp directory?) - hence the pathForResource: method returns nil (the resource is not found within the app bundle), and NSData initializer fails when the path is nil -> returns nil as well.
You most likely want this: NSData *fileData = [NSData dataWithContentsOfFile:filePath];.
Few notes:
do not use isEqual:nil. Simply use filePath != nil (it's easier to read and it's faster on execution).
NSString has a pathExtension property, which will retrieve the property for you.
using file paths is unofficially deprecated in favor of using URLs: NSURL *fileURL = [NSURL fileURLWithPath:filePath]; You should use URLs in new code.
Please, post a sample value of filePath if this doesn't help.
Related
I am trying to upload a pdf from iClouds in iPhone in Objective C. The following is my code which gets triggered on click.
UIDocumentPickerViewController *doc = [[UIDocumentPickerViewController alloc]initWithDocumentTypes:#[#"public.composite-content"] inMode:UIDocumentPickerModeImport];
doc.delegate = (id)self;
doc.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:doc animated:YES completion:nil];//getting the path of the file selected through didPickDocumentAtURL
NSString *path = [url path];//converting in to data in two different ways but getting truncated nsdata
NSData *data3 = [[NSFileManager defaultManager] contentsAtPath:path];//Truncating
NSData *data1 = [NSData dataWithContentsOfFile:path];//Truncating Both data3 and data1 are getting truncated after 32767 characters.
Questions:
Is this correct format for importing a .pdf into NSData?
Is there any limit for NSData? (I am asking this because it's getting truncated exactly after 32767 characters)
I solved it by calling the delegate method of UIDocumentPickerViewController
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url{
if (controller.documentPickerMode== UIDocumentPickerModeImport) {
//taking the path of the file selected
NSString *path = [url path];
//converting to NSData
NSData *data = [[NSFileManager defaultManager] contentsAtPath:path];
//converting to base64 string
base64String = [data base64EncodedStringWithOptions:kNilOptions];
}
}
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];
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.
I am developing native iOS application.
I have a requirement as copy an image from my application to mail app, how can i accomplish the task kindly suggest me.
Thanks in Advance..
using MFMailComposeViewController
MFMailComposeViewController *mail=[MFMailComposeViewController alloc]init];
// Determine the file name and extension
NSString *extension =#"png";
NSString * filename=#"email";
// 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
[mail addAttachmentData:fileData mimeType:mimeType fileName:filename];
Use MFMailComposerController and use this code:
MFMailComposeViewController * mcvc = [[MFMailComposeViewController alloc] init];
mcvc = self;
[mcvc setSubject:#"Subject"];
[mailer setToRecipients:#[#"mail#domain.com"]];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"mrweb" ofType:#"png"];
NSData *imageData = [NSData dataWithContentsOfFile:filePath];
[mcvc addAttachmentData:imageData mimeType:#"image/png" fileName:#"allegato1.png"];
[mcvc setMessageBody:#"Hello bro !" isHTML:NO];
[self presentViewController:mcvc animated:YES completion:^{}];
If you have an UIImage use
NSData *imageData = UIImagePNGRepresentation(myImage.image);
to convert UIImage in NSData.
Here the complete list of all mime-types.
i try to send a audio record by file aac (kAudioFormatMPEG4AAC) format but the file attached it's doesn't send
*myString = file://localhost/private/var/mobile.......
here is my code
MFMailComposeViewController *picker =
[[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"My Audio File"];
NSString *fileName = #"Rec.aac";
NSString *documentsDirectory = myString ;
NSString *path = [documentsDirectory stringByAppendingPathComponent:fileName];
NSData *data = [NSData dataWithContentsOfFile:path];
[picker addAttachmentData:data mimeType:#"audio/aac"
fileName:fileName];
NSString *emailBody = #"AAC format sound file attached.";
[picker setMessageBody:emailBody isHTML:YES];
[self presentModalViewController:picker animated:YES];
[picker release];
NSData *data = [NSData dataWithContentsOfFile:path];
You're passing in a file:// URL, which won't be understood by that method. That method expects just a standard file path, i.e. /private/var/mobile/.
You could simply use the file path, but if you're only provided with a URL form string, you can create a URL object and use that with NSData.
NSURL* fileURL = [NSURL URLwithString:myString];
NSError* error = nil;
NSData* data = [NSData dataWithContentsOfURL:fileURL options:0 error:&error];
if (error) {
NSLog(#"Unable to load file from provided URL %#: %#", myString, error);
}