MFMailComposeViewController IOS - ios

At the moment I have a NSArray of emails, and I open a view to end an email to all of these emails:
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:#"App Support"];
NSArray *toRecipients = [NSArray arrayWithArray:emails];
[mailer setToRecipients:toRecipients];
NSString *emailBody = #"";
[mailer setMessageBody:emailBody isHTML:NO];
// only for iPad
mailer.modalPresentationStyle = UIModalTransitionStylePartialCurl;
[self presentModalViewController:mailer animated:YES];
Is there a way to send an email to this list without opening actually opening the controller (the user won't need to press on the send button and can't change the message)??

There's no way to send the message using the MFMailComposeViewController.
If you want to send an email "silently", I have previously used SKPSMTPMessage - an SMTP client that can be used on iOS to send emails without any UI.
You can set up a Gmail account specifically for the purpose of sending the messages if required.
I've created a simple demo for you. Download it here. Note that, along with the files in the SMTP folder, you will need to link to the CFNetwork.framework in your project.

Related

Sending email without presenting a view

I need send a email without presenting a MFMailComposeViewController In a few words, I need to send the E-mail directly without the user pressing the send button and to show the view.
My code is:
MFMailComposeViewController *mail = [[MFMailComposeViewController >alloc] init];
mail.mailComposeDelegate = self;
[mail setSubject:#"Recordatorio de clave"];
[mail setMessageBody:message isHTML:NO];
[mail setToRecipients:#[email]];
[self presentModalViewController:mail animated:YES];
My answer is YES, You can send email from background without presenting MFMailComposeVC
There are two ways to do this
1- Either write a webservice that will send an email from background when it will be called.
2- You can send email by using SMTP gmail account. For this you will have to use SKPSMTPMessage Library. Here is a good tutorial for it.
if you don't want to use MFMailComposeViewController, you can use SMTP for this. please check this link Sending e-mail in background from iOS apps using SMTP gmail account
This is not possible with MFMailComposeViewController
You can create web service and pass data to it and your server can send mail.
You can't directly use MFMailComposeViewController for that need to external library or program need to us for sending mail using SMTP here I mention gmail thru sending mail without interaction of users.
Code for .h file
#import <UIKit/UIKit.h>
#import "SKPSMTPMessage.h"
#interface mailTransferViewController : UIViewController<SKPSMTPMessageDelegate>{
IBOutlet UITextField *emailField;
}
- (IBAction)sendMessageInBack:(id)anObject;
#end
Code for .m file
- (IBAction)sendMessageInBack:(id)anObject{
NSLog(#"Start Sending");
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"sample.pdf"];
NSData *dataObj = [NSData dataWithContentsOfFile:writableDBPath];
SKPSMTPMessage *testMsg = [[SKPSMTPMessage alloc] init];
testMsg.fromEmail = #"Yours mail ids";
testMsg.toEmail = emailField.text;//sender mail id
testMsg.relayHost = #"smtp.gmail.com";
testMsg.requiresAuth = YES;
testMsg.login = #"Your mail ids";
testMsg.pass = #"Mail id password";
testMsg.subject = #"Test application ";
testMsg.wantsSecure = YES; // smtp.gmail.com doesn't work without TLS!
// Only do this for self-signed certs!
// testMsg.validateSSLChain = NO;
testMsg.delegate = self;
NSDictionary *plainPart = [NSDictionary dictionaryWithObjectsAndKeys:#"text/plain",kSKPSMTPPartContentTypeKey,#"Some text to include in body",kSKPSMTPPartMessageKey,#"8bit",kSKPSMTPPartContentTransferEncodingKey,nil];
//Logic for attach file.
// NSDictionary *vcfPart = [NSDictionary dictionaryWithObjectsAndKeys:#"text/directory;\r\n\tx-unix-mode=0644;\r\n\tname=\"sample.pdf\"",kSKPSMTPPartContentTypeKey,#"attachment;\r\n\tfilename=\"sample.pdf\"",kSKPSMTPPartContentDispositionKey,[dataObj encodeBase64ForData],kSKPSMTPPartMessageKey,#"base64",kSKPSMTPPartContentTransferEncodingKey,nil];
// NSLog(#"%#",vcfPart);
// testMsg.parts = [NSArray arrayWithObjects:plainPart,vcfPart,nil];
// testMsg.parts = [NSArray arrayWithObjects:plainPart,vcfPart,nil];
testMsg.parts = [NSArray arrayWithObjects:plainPart,nil];
[testMsg send];
}
No, its not possible to send the mail. In the iOS you can not perform like that, you have to write a web based API for doing that.
That's not possible the user only has the permit to send the mail from the device. You can only compose the email. If you have to archive such kind of functionality just create it on Backend and trigger it from the device by calling webservice.
Sending emails programmatically, without user intervention, from an iphone application, cannot be implemented using any of the Apple frameworks. It could be possible in a jailbroken phone but then it would never see the inside of App Store.
If you want control of email sending, then a better way would be to set up a web service (at your server end) you can post to using an HTTP request. If you are posting to only one address this can work very well, although you may want to get the user to input their return mail address.
Otherwise only the standard dialog is available (this relies on using whatever account they've setup on the device).

Displaying pdf document in MFMailComposeViewController

I've read posts that say the the `MFMailComposeViewController should display your attached PDF if its a 1 page document but for some reason my PDF is always showing up as just an icon. I want it to display the PDF since its only 1 page. The PDF seems to be fine since I can send the email and I can open it in the mail app or on my computer.
Is this not enabled by default in iOS 6.0 or later or is there something im missing?
MFMailComposeViewController* controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
// create the message body.
NSMutableString *body = [[NSMutableString alloc] init];
// add the user name to the email body.
[body appendFormat:#"Name: %#", userName];
// add the pdf to the email.
NSData *data = [NSData dataWithContentsOfFile:path];
[controller addAttachmentData:data mimeType:#"application/pdf"
fileName:#"test.pdf"
includeExtension:YES]];
// add the body string to the email body.
[controller setMessageBody:body isHTML:NO];
// show the email controller.
[self presentViewController:controller animated:YES completion:nil];

MFMailComposeViewController canSendMail returns YES but not sending mail in iOS

The following is my code to send an attachment in a mail. This works fine. I am able to send mails but I don't always receive the mails.
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
// Set the subject of email
[picker setSubject:#"My data file"];
// Add email addresses
[picker setToRecipients:[NSArray arrayWithObjects:emailId, nil]];
// Fill out the email body text
NSString *emailBody = #"Hello, \n Please find the data from the iOS app in the attachments.\n\n Thank you.\nMy Team.";
// This is not an HTML formatted email
[picker setMessageBody:emailBody isHTML:NO];
// Create NSData object from file
NSData *exportFileData = [NSData dataWithContentsOfFile:filePath];
// Attach image data to the email
[picker addAttachmentData:exportFileData mimeType:#"text/csv" fileName: [self.CSVNameTextField text]];
// Show email view
if ([MFMailComposeViewController canSendMail]) {
[self presentModalViewController:picker animated:YES];
}
After you send the Mail with your App go to the Mail-Software on your iPhone, you will most likely find the mail in the Outbox.
Cause the MFMailComposeViewController will just forward the Mail to the Mail-Software and it doesn't care what happens next to the message. So it's up to your Mail-Software how and when the Outbox will be updated.
I had the same problem, I found that it would go through the mail box and say it had sent and then nothing would come through.
About 20-30 minutes later the first one came through and then gradually the rest I sent came through too.
I don't know why it takes so long, if I find out I will edit this answer, but definitely wait up to an hour before assuming your code is broken.
Hope this helps someone who, like me, might be trawling their code over and over
In my case i had to manually open up the iphone mail app, then mails were sent and received immediately.

issue when multiple recipients for my app mail- Objective c

I am facing a problem when multiple recipients for my mail, i have two attachments there by default.Is there anything i have to do when iam sending a mail to multiple recipients other than the below code; (I have to select or type recipient id's from UI)
if ([MFMailComposeViewController canSendMail])
{
[self printPdfAndCsv];// code to generate pdf & csv
MFMailComposeViewController* mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
// attaching PDF File.
[mailComposer addAttachmentData:[NSData dataWithContentsOfFile:self.pdfFilePath]
mimeType:#"Application/pdf" fileName:[NSString stringWithFormat:#"pdfName-%#.pdf", selectedProjectName ]];
// attaching CSV File.
[mailComposer addAttachmentData:[NSData dataWithContentsOfFile:self.csvFilePath]
mimeType:#"text/csv" fileName:[NSString stringWithFormat:#"csvName-%#.csv", selectedProjectName ]];
[self presentViewController:mailComposer animated:YES completion:nil];
}
Iam a starter in iPhone development, so i need your valuable help.
Try this
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
NSArray *toRecipients = [NSArray arrayWithObjects:#"abc#gmail.com",#"xyz#gmail.com",nil];
[picker setToRecipients:toRecipients];
If you want to sent mail to multiple user then you can use:
[mailController setToRecipients:[NSArray arrayWithObject:#"email#address.com",#"email1#address.com",#"email#address.com",nil]];
I got a solution from rmaddy on his comment,
There may be problem with one of the email addresses we tested.
Maybe the email ended up appearing as junk mail (spam).
Once the user taps Send, it's out of our control.
(and in my case; i found the mails that i have sent were in spam box)

Attaching a PKPass to Email in Code

I am using PassSlot which creates a Pass on the fly that can be added to passbook. I am trying to get it downloaded to the device to allow attaching to an email. Here is what I have so far:
[PassSlot passFromTemplateWithName:#"LoveCouponCards" withValues:values pass:^(PSPass *pass) {
[PassSlot downloadPass:pass pass:^(PSPass *pass) {
PKPass *pkpass = [pass performSelector:#selector(pass)];
NSLog(#"Pass: %#", pkpass);
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
NSArray *toRecipients = [NSArray arrayWithObject:#"friend#example.com"];
[picker setToRecipients:toRecipients];
[picker addAttachmentData:pkpass mimeType:#"application/vnd.apple.pkpass" fileName:#"HI"];
// Fill out the email body text
NSString *emailBody = \\
[picker setMessageBody:emailBody isHTML:NO];
[self presentViewController:picker animated:YES completion:nil];
}];
}];
The issue is that in the addAttachment part for the email, it throws an error that NSData can't relate to PKPass basically. How can I get pass converted to NSData so I can attach it?
UPDATE:
I tried doing
NSURL *url = pkpass.passURL;
NSData *so = [NSData dataWithContentsOfURL:url];
and then putting 'so' as the addAttachment, but it attached nothing to the email.
Firstly, the passURL property of PKPass doesn't quite work the way you think. It is not a URL to the pass itself. It is a URL that opens up the Passbook app and loads up that requested pass.
You can create a PKPass with NSData, but you can't reverse that process. It sounds as if you are trying to get a pass on device, and then e-mail it. That's not allowed - if it was, people could easily copy and distribute passes around (which isn't necessarily a good thing).
If you want to e-mail a user a pass you need to do it server, rather than client side. I'm afraid that what you're trying to do isn't possible using PassKit. Sorry!
Unfortunately the PassKit library does not provide a way to get back the NSData from a PKPass.
We already provide an API call that allows you to get the raw data of a pass.
We will extend our PassSlot SDK with a method that allows you to get the NSData without having the manually call this API method.
Update
The new SDK version 0.5 is now released. You can attach the pass with the following code:
[PassSlot passFromTemplateWithName:#"LoveCouponCards" withValues:values pass:^(PSPass *pass) {
[PassSlot downloadPass:pass pass:^(PSPass *pass) {
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setToRecipients:#[#"friend#example.com"]];
[picker addAttachmentData:pass.data mimeType:#"application/vnd.apple.pkpass" fileName:#"LoveCouponCard.pkpass"];
[picker setMessageBody:emailBody isHTML:NO];
[self presentViewController:picker animated:YES completion:nil];
}];
}];

Resources