Send a mail programmatically in Sprite Kit - ios

I've tried to send mails programmatically using the MessageUI framework. This is what I have in MyScene.m. When I call the method, a mail window opens. But when I cancel the mail or when I send the mail, it doesn't goes back to MyScene.
#import <MessageUI/MessageUI.h>
-(void)sendMail
{
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:#"Subject"];
[mc setMessageBody:#"Hello!" isHTML:NO];
[mc setToRecipients:[NSArray arrayWithObject:#"my.email#gmail.com"]];
// Present mail view controller on screen
[self.view.window.rootViewController presentViewController:mc animated:YES completion:NULL];
}
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled");
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved");
break;
case MFMailComposeResultSent:
NSLog(#"Mail sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Mail sent failure: %#", [error localizedDescription]);
break;
default:
break;
}
// Close the Mail Interface
[self.view.window.rootViewController dismissViewControllerAnimated:YES completion:NULL];
}

You are setting the scene as a delegate for MFMailComposeViewController:
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
Change it to
mc.mailComposeDelegate = self.view.window.rootViewController;
But that's of course a bad practice. SKScene is a presentation layer. You should present MFMailComposeViewController from UIViewController.
EDIT:
Add this code to GameSceneViewController:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(sendMail) name:#"showMailComposer" object:nil];
}
-(void)sendMail
{
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:#"Subject"];
[mc setMessageBody:#"Hello!" isHTML:NO];
[mc setToRecipients:[NSArray arrayWithObject:#"my.email#gmail.com"]];
// Present mail view controller on screen
[self.view.window.rootViewController presentViewController:mc animated:YES completion:NULL];
}
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled");
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved");
break;
case MFMailComposeResultSent:
NSLog(#"Mail sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Mail sent failure: %#", [error localizedDescription]);
break;
default:
break;
}
// Close the Mail Interface
[self dismissViewControllerAnimated:YES completion:NULL];
}
Call this when you want to send a mail:
[[NSNotificationCenter defaultCenter] postNotificationName:#"showMailComposer" object:nil];

Related

MFMailComposeViewController delegate not called

I'm not able to call Mail composer delegate method even if I'm writing below code:
-(void)openMailComposerInViewController:(UIViewController *)hostController{
if ([MFMailComposeViewController canSendMail])
{
// Email Subject
NSString *emailTitle = #"Test Email";
// Email Content
NSString *messageBody = #"Test Email";
// To address
NSArray *toRecipents = [NSArray arrayWithObject:#"support#test.com"];
mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
[mailComposer setSubject:emailTitle];
[mailComposer setMessageBody:messageBody isHTML:NO];
[mailComposer setToRecipients:toRecipents];
// Present mail view controller on screen
[hostController presentViewController:mailComposer animated:YES completion:NULL];
mailController = hostController;
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Failure"
message:#"Your device doesn't support the composer sheet"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
pragma mark - Mail
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled");
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved");
break;
case MFMailComposeResultSent:
NSLog(#"Mail sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Mail sent failure: %#", [error localizedDescription]);
break;
default:
break;
}
// Close the Mail Interface
[mailController dismissViewControllerAnimated:YES completion:NULL];
}
I do not want to call mail composer on self
However, my delegate is not getting called. Please help. The application crashed on clicking on Cancel or Send mail button
I experienced this problem, and my problem was I had the following code:
self.mailComposer.mailComposeDelegate = self
self.mailComposer = MFMailComposeViewController()
I was setting the delegate before I initialized the mailComposer object. I just switched those 2 lines to this and it worked:
self.mailComposer = MFMailComposeViewController()
self.mailComposer.mailComposeDelegate = self
Because of ARC, I was losing the viewcontroller in which the delegate was written so it was not gettting called. Below code helped me fix the issue:
+(MailComposer *)sharedInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMailComposer = [[MailComposer alloc]init];
});
return sharedMailComposer;
}
Then I used the above instance while calling the MailComposerViewController
[[MailComposer sharedInstance] openMailComposerInViewController:[(UINavigationController *)moduleRouter.container topViewController]];
It Worked :)
your class instance must be same for setMailComposeDelegate and presentViewController.
mailComposer.mailComposeDelegate = hostController;
[hostController presentViewController:mailComposer animated:YES completion:nil];

dismissViewControllerAnimated: does not work

I have a method to send an email from my table view.
So one of the cells is a "contact us" cell, and whenever it's tapped I get to the mail view controller using MFMailComposeViewController , but the problem is that when I tap "cancel" or "send" my mail view controller does not go back to the table view. the "cancel" and "send" actions work, but I stay on the mail view controller.
This is the relevant methods:
- (void)sendEmail {
// Email Subject
NSString *emailTitle = #"Test Email";
// Email Content
NSString *messageBody = #"iOS programming is so fun!";
// To address
NSArray *toRecipents = [NSArray arrayWithObject:#"kkk#gmail.com"];
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:messageBody isHTML:NO];
[mc setToRecipients:toRecipents];
// Present mail view controller on screen
[self presentViewController:mc animated:YES completion:NULL];
}
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled");
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved");
break;
case MFMailComposeResultSent:
NSLog(#"Mail sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Mail sent failure: %#", [error localizedDescription]);
break;
default:
break;
}
// Close the Mail Interface
[self dismissViewControllerAnimated:YES completion:NULL];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
SettingsControllerSection section = indexPath.section;
if (OtherControllerSection == section) {
SettingsControllerOtherSection row = indexPath.row;
switch (row) {
case RateUsController:
NSLog(#"rate us was pressed");
break;
case ContactUsControllerRow:
[self sendEmail];
NSLog(#"send email was pressed");
break;
}
}
}
please help, thanks!!
In mailComposeController method dismiss it like this:
[controller dismissViewControllerAnimated:YES completion:NULL];

EmailDialog not closing when send or even cancelling

i want to send an email, but when i click on send it really sends that email but the view is not closed.
MainViewController.m
NSString *text = [self fetchLogCoreData];
PlistCreatorViewController *plistCreator = [[PlistCreatorViewController alloc] init];
[plistCreator sendPlist2Email:self text:text];
I'm fetching all data in coreData and then put it into an NSString.
Then call sendPlist2Email with self as the view and text as the text i want to use in email.
PlistCreatorViewController.m
-(void)sendPlist2Email: (UIViewController*) viewController text:(NSString*)text{
NSString *emailTitle = #"PickDPack App: DATA";
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:text isHTML:NO];
// Determine the file name and extension
// Get the resource path and read the file using NSData
// Add attachment
[viewController presentViewController:mc animated:YES completion:nil];
}
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled");
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved");
break;
case MFMailComposeResultSent:
NSLog(#"Mail sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Mail sent failure: %#", [error localizedDescription]);
break;
default:
break;
}
MainViewController *mainView = [[MainViewController alloc] init];
// Close the Mail Interface
NSLog(#"Email_out");
[mainView dismissViewControllerAnimated:YES completion:NULL];
}
Really simple, im sending the email but the window doesn't close when i press send/cancel.
I've tried to put selfinto [mainView dismissViewControllerAnimated:YES completion:NULL]; changing mainViewbut nothing change.
I've put this code inside MainViewController.mbut nothing change.
I hope anyone could help me :S
Thx
Have you tried as like below?
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
[controller dismissViewControllerAnimated:YES completion:NULL];
}

MFMailComposeViewController doesn't close

I have an app where I use E-Mail to developer Button. When I press the button VEMailView-controller opens.
This is just wrapper for MFMailComposeViewController.
When I press "send" button, the controller have to be closed but I see just white window. No more. It must be closed to main ViewController. How to fix?
This is my code:
#import <MessageUI/MessageUI.h>
#import "VEMailView.h"
#interface VEMailView () <
MFMailComposeViewControllerDelegate,
UINavigationControllerDelegate
>
// UILabel for displaying the result of the sending the message.
#end
#implementation VEMailView{
BOOL alreadyOpened;
}
- (void)viewDidLoad
{
[super viewDidLoad];
alreadyOpened = NO;
}
- (void) viewDidAppear:(BOOL)animated {
[self showMailPicker];
}
- (void)showMailPicker
{
if ([MFMailComposeViewController canSendMail])
{
[self displayMailComposerSheet];
}
}
- (void)displayMailComposerSheet
{
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"iOS"];
NSArray *toRecipients = [NSArray arrayWithObject:#"first#example.com"];
[picker setToRecipients:toRecipients];
NSString *emailBody = #" ";
[picker setMessageBody:emailBody isHTML:NO];
[self presentViewController:picker animated:YES completion:NULL];
}
- (void)mailComposeController:(MFMailComposeViewController*)controller
didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Result: Mail sending canceled");
break;
case MFMailComposeResultSaved:
NSLog(#"Result: Mail saved");
break;
case MFMailComposeResultSent:
NSLog(#"Result: Mail sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Result: Mail sending failed");
break;
default:
NSLog(#"Result: Mail not sent");
break;
}
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
That's because you are making an extra view controller. Create the MFMailComposeViewController in the view controller where the button is. The mail compose controller is a controller by itself. There is a white screen because that is the default view of YOUR VEMailView. Get rid of that and put these methods:
- (void)showMailPicker;
- (void)displayMailComposerSheet;
in the view controller with the button. Also make it the delegate.
I found my own solution.
To solve this problem change
[self dismissViewControllerAnimated:YES completion:nil];
into
[self dismissViewControllerAnimated:YES completion:^{[self dismissViewControllerAnimated:YES completion:nil];}];
Thanks Michal for idea.

dismissViewControllerAnimated: moves my viewcontroller to initial controller

I tried to mail from imageviewcontroller and it works properly and the mail is send with the captured image successfully. when the send button is pressed, the mailcomposeviewcontroller is dismissed and shows the intial controller used for login purpose, but actually it should move to the current view controller i.e., imageviewcontroller..
Code used in imageviewcontroller,
- (IBAction)mail_button:(id)sender
{
if ([MFMailComposeViewController canSendMail])
{
UIGraphicsBeginImageContext(self.view.bounds.size);
composeViewController = [[MFMailComposeViewController alloc] init];
// [composeViewController setMailComposeDelegate:self];
composeViewController.mailComposeDelegate = self;
// [composeViewController setToRecipients:#[#"example#email.com"]];
[composeViewController setSubject:#"Dressface Mail"];
[composeViewController setMessageBody:#"HI i am using dressface application its very awesome you too try this." isHTML:NO];
UIImage *myimage = [UIImage imageNamed:#"Default.png"];
NSData *imgdata = UIImagePNGRepresentation(myimage);
[composeViewController addAttachmentData:imgdata mimeType:#"image/png" fileName:#"Dressfaceimage"];
[self presentViewController:composeViewController animated:YES completion:nil];
}
}
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled");
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved");
break;
case MFMailComposeResultSent:
NSLog(#"Mail sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Mail sent failure: %#", [error localizedDescription]);
break;
default:
break;
}
// Close the Mail Interface
[controller dismissViewControllerAnimated:YES completion:nil];
}
Can anyone help me to dismiss the mailcomposeviewcontroller and go back to previous controller where the mail_button was placed.
You shouldn't dismiss MFMailComposeViewController passed in didFinishWithResult method as it manages the mail composition view. You should instead call
[self dismissViewControllerAnimated:YES completion:nil];
as it will dismisses the view controller that was presented by the receiver, that is the view controller on which you presented MFMailComposeViewController.
You can also write this line in delegate method to dismiss MFMailComposeViewController
[[controller presentingViewController] dismissViewControllerAnimated:YES completion:nil];

Resources