0

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?

Community
  • 1
  • 1
  • Have you made sure that the attachment was not stripped by the client? There are some email hosts that remove attachments of a certain type for security reasons. – Putz1103 Jun 23 '15 at 16:42
  • Good question. How do I trouble-shoot if this is mail host removing my file? What's the recommended Xcode to check and handle this type of issue before/after sending email with attachment? – Yuan-Lu Chang Jun 26 '15 at 22:28
  • There is no way to resolve that and no way of testing within xcode. The only options are to try a different email provider or try to send the exact same attachment from your own email system tot he same address and see if the attachment gets stripped. – Putz1103 Jun 29 '15 at 13:35
  • Just tried yahoo and gmail both and no luck. PDF attachment still gets stripped out. In addition, it adds another attached .txt file automatically which says "Sent from my iPad". – Yuan-Lu Chang Jun 29 '15 at 20:07

1 Answers1

0

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