This is a really weird issue! I have a button on screen which when pressed launches the MFMailComposeViewController using the following code:
-(IBAction) openComposeEmailScreen:(id) sender {
if([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailComposeViewController = [[MFMailComposeViewController alloc] init];
mailComposeViewController.mailComposeDelegate = self;
[mailComposeViewController setToRecipients:[NSArray arrayWithObject:#"johndoe#gmail.com"]];
[mailComposeViewController setSubject:#"HelloWorld"];
NSLog(#"%#",_pasteBoard.string);
[mailComposeViewController setMessageBody:_pasteBoard.string isHTML:NO];
[self presentViewController:mailComposeViewController animated:YES completion:nil];
}
}
-(void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
if(error) {
NSLog(#"%#",error.localizedDescription);
}
[self dismissViewControllerAnimated:YES completion:nil];
}
Also, my view controller uses the correct protocol:
ViewController ()<MFMailComposeViewControllerDelegate>
I am running this on the simulator.
MFMailComposeViewController isn't supported in the simulator. You have to run on a device.
Related
This question already has answers here:
Objective C: Send email without leaving app
(3 answers)
Closed 3 years ago.
I want to send mail while clicking a button in a custom UITableViewCell using MFMailComposeViewController.
Appreciate if answer is in Objective-C.
Following code in your .h file
#import <MessageUI/MFMailComposeViewController.h>
Give Delegate <MFMailComposeViewControllerDelegate>
Following code in your .m file
//Where you want to open dialog write below code
if([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailCont = [[MFMailComposeViewController alloc] init];
mailCont.mailComposeDelegate = self; // Required to invoke mailComposeController when send
[mailCont setSubject:#"Your Subject!"];
[mailCont setToRecipients:[NSArray arrayWithObject:#"hello#test.com"]];
[mailCont setMessageBody:#"Your Body" isHTML:NO];
[self presentViewController:mailCont animated:YES completion:nil];
}
//Delegate Method
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result)
{
case MFMailComposeResultCancelled:
//YOUR ACTION
break;
case MFMailComposeResultSent:
//YOUR ACTION
break;
case MFMailComposeResultSaved:
//YOUR ACTION
break;
case MFMailComposeResultFailed:
//YOUR ACTION
break;
default:
break;
}
}
You can dismiss view by this code - [self dismissViewControllerAnimated:YES completion:nil];
Make sure you are testing it in Real device not in simulator and you have a mail ID configured in your device
#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>
#interface ViewController ()<MFMailComposeViewControllerDelegate>
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)sendmail:(id)sender {
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:#"Subject"];
NSArray *toRecipients = [NSArray arrayWithObjects:#"Recipients", nil];
[mailer setToRecipients:toRecipients];
NSString *emailBody = #"Body";
[mailer setMessageBody:emailBody isHTML:NO];
[self presentViewController:mailer animated:YES completion:nil];
}
}
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
// Close the Mail Interface
[self dismissViewControllerAnimated:NO completion:NULL];
}
I just need to display the email composer on my iOS simulator (No need to send the actual mail).
As soon as I am initializing the MFMailComposeViewController I am getting alert pop - up saying that email account is not set.
This is what I am doing.
MFMailComposeViewController* composeVC = [[MFMailComposeViewController alloc] init];
This line pops up the alert controller.
For simulator email configuration is not available.
Use the below code to send email.
- (void)openEmail
{
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mail =
[[MFMailComposeViewController alloc] init];
mail.mailComposeDelegate = self;
[mail setSubject:#"Subject"];
[mail setMessageBody:#"body message" isHTML:NO];
[mail setToRecipients:#[#"email1#example.com",#"email2#example.com"]];
/// if attachment then implement below line
//[mail addAttachmentData:<#(nonnull NSData *)#> mimeType:<#(nonnull NSString *)#> fileName:<#(nonnull NSString *)#>]
[self presentViewController:mail animated:YES completion:NULL];
}
else {
NSLog(#"Please configure your email. Settings->Accounts & Passwords->Add Account");
}
}
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(nullable NSError *)error
{
switch (result) {
case MFMailComposeResultSent:
NSLog(#"Sent");
break;
default:
break;
}
}
I've a class that subclass NSObject with a function do display a MFMailComposeViewController. Here is the code :
MFMailComposeViewController *mailController = [[MFMailComposeViewController alloc] init];
mailController.mailComposeDelegate = self;
[mailController setSubject:#"Sample Subject"];
[mailController setMessageBody:#"Here is some main text in the email!" isHTML:NO];
[mailController setToRecipients:#[self.email]];
UITabBarController *tabbarController = (UITabBarController *)[UIApplication sharedApplication].keyWindow.rootViewController;
UINavigationController *navigationController = tabbarController.selectedViewController;
[navigationController.topViewController presentViewController:mailController animated:YES completion:NULL];
Everything works well with this code. The problem is when I want to dismiss the MFMailComposeViewController. Sometime I get a crash, sometimes it just don't happens nothing. I've implemented the delegate function :
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
UITabBarController *tabbarController = (UITabBarController *)[UIApplication sharedApplication].keyWindow.rootViewController;
UINavigationController *navigationController = tabbarController.selectedViewController;
[navigationController.topViewController dismissViewControllerAnimated:YES completion:nil];
}
After that I tried to show and dismiss it directlty from a ViewController and everything was working. Even the cancel button.
I don't know why it works in my ViewController Class but not in my subclass of NSObject.
When I get the crash I've seen in the logs :
-[MFMailComposeInternalViewController _notifyCompositionDidFinish]
Try this,
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
// Do your work and dismiss after you are done with it.
[controller dismissViewControllerAnimated:YES completion:nil];
}
Hope that helps.
Try this in your singleton class
UIViewController *currentViewController;
- (void)sendEmail:(id) viewController {
currentViewController=(UIViewController*)viewController;
NSString * appVersionString =#"";
NSString *strEmailMessage=#"";
NSString *strEmailSubject=#"";
NSArray *toRecipents =#"";
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate =viewController;
[mc setSubject:strEmailSubject];
[mc setMessageBody:strEmailMessage isHTML:NO];
[mc setToRecipients:toRecipents];
[viewController presentViewController:mc animated:YES completion:NULL];
}
else{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Error" message:#"Please setup email account" delegate:nil cancelButtonTitle:#"cancle" otherButtonTitles:nil];
[alert show];
}
}
set delegate like this
mc.mailComposeDelegate =viewController;
to dissmiss viewController
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result)
{
case MFMailComposeResultCancelled:
break;
case MFMailComposeResultSaved:
break;
case MFMailComposeResultSent:
break;
case MFMailComposeResultFailed:
break;
}
// Close the Mail Interface
[currentViewController dismissViewControllerAnimated:YES completion:NULL];
}
i hope this will work...
I am new to this,
I have this code in my viewController,
- (void)sendMail:(id)sender {
NSArray *to = [NSArray arrayWithObjects:#"rayjada11#gmail.com", nil];
mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
[mailComposer setToRecipients:to];
[mailComposer setSubject:#"Test Mail"];
[mailComposer setMessageBody:#"Testing message body" isHTML:NO];
[self presentModalViewController:mailComposer animated:YES];
}
#pragma mark - mail compose delegate
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
if(result) {
NSLog(#"Result = %d", result);
}
if(error) {
NSLog(#"Error = %#", error);
}
[self dismissModalViewControllerAnimated:YES];
}
But when I click send button in my controller, I am getting error like,
2016-09-05 14:55:24.488 mailDemo[1276:104171]
viewServiceDidTerminateWithError: Error
Domain=_UIViewServiceInterfaceErrorDomain Code=3 "(null)"
UserInfo={Message=Service Connection Interrupted} 2016-09-05
14:55:24.989 mailDemo[1276:104171] Trying to dismiss the presentation
controller while transitioning already.
(<_UIFullscreenPresentationController: 0x7fe35b52d2a0>) 2016-09-05
14:55:24.991 mailDemo[1276:104171] transitionViewForCurrentTransition
is not set, presentation controller was dismissed during the
presentation? (<_UIFullscreenPresentationController: 0x7fe35b52d2a0>)
What is the issue?
There is nothing wrong with your code.MFMailComposeViewController is not work for simulator, Try same code in real device.
simulator doesn't supported method and device doesn't login in mail that this method nothing response.
replace this method ::
- (void)sendMail:(id)sender {
if (![MFMailComposeViewController canSendMail]) {
NSLog(#"Mail services are not available.");
return;
}
else{
NSArray *to = [NSArray arrayWithObjects:#"rayjada11#gmail.com", nil];
mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
[mailComposer setToRecipients:to];
[mailComposer setSubject:#"Test Mail"];
[mailComposer setMessageBody:#"Testing message body" isHTML:NO];
[self presentModalViewController:mailComposer animated:YES];
}
}
MFMailComposeViewController does not work for simulators. If you try the same code in real device, it will work. There is nothing wrong with your code.
I am new to xcode, and am wondering how to send email in an app! My code is below, but I keep getting an error for the "self presentModalViewController" line. Is my code completely wrong? Or did I just forget to declare the selector, and how do I declare the selector? Someone please help me
MFMailComposeViewController* controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:#"My Subject"];
[controller setMessageBody:#"Hello there." isHTML:NO];
if (controller)[self presentModalViewController:controller animated:YES];
}
- (void)mailComposeController:(MFMailComposeViewController*)controller
didFinishWithResult:(MFMailComposeResult)result
error:(NSError*)error;
{
if (result == MFMailComposeResultSent) {
NSLog(#"It's away!");
}
[self dismissModalViewControllerAnimated:YES];
}
please present your mail composer using
[self presentViewController:controller animated:YES];