MFMailComposeViewController's delegate not handling the CANCEL button [duplicate] - iphone

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Action sheet doesn't display when the MFMailComposeViewController's cancel button is tapped
I've implemented standard mail functionality in my app according to the code sample provided by Apple.
I'm setting up the delegate as follows:
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
and I'm implementing
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
Hitting the Send button invokes the delegate and it all works fine. However, hitting the Cancel button doesn't call the delegate and it just dims the view; the app hangs right there.
After reading similar threads here, I've been thinking that the view could be off-screen for some reason which is beyond my comprehension at this point. Note that the view is being created programmatically and is not using a xib file.
Any thoughts or ideas ?

You need to implement mailComposeController:didFinishWithResult:error delegate. And in that you dismiss the view which is showing your mail view. If you have opened the mail view as a modalView, then the way to dismiss this is -
- (void)mailComposeController:(MFMailComposeViewController*)controller
didFinishWithResult:(MFMailComposeResult)result
error:(NSError*)error
{
if(error) NSLog(#"ERROR - mailComposeController: %#", [error localizedDescription]);
[self dismissModalViewControllerAnimated:YES];
return;
}

It may be helpful to you
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
// Notifies users about errors associated with the interface
switch (result)
{
case MFMailComposeResultCancelled:
//NSLog(#"Result: canceled");
break;
case MFMailComposeResultSaved:
//NSLog(#"Result: saved");
break;
case MFMailComposeResultSent:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Result" message:#"Mail Sent Successfully" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
break;
case MFMailComposeResultFailed:
//NSLog(#"Result: failed");
break;
default:
//NSLog(#"Result: not sent");
break;
}
[self dismissModalViewControllerAnimated:YES];
}

Try to add even simple delegate :
[picker setDelegate:self];

Related

wait_fences: failed to receive reply: 10004003 error occur while click on button (send, cancel) of MFmessgecompose model iOS [duplicate]

This question already has answers here:
"wait_fences: failed to receive reply: 10004003"?
(18 answers)
Closed 9 years ago.
I want to popup MFMessageCompose model on (topviewcontroller) from another NSObject class method which is executed in background.
I popup MFMessageCompose model using this code :
MFMessageComposeViewController * controller = [[MFMessageComposeViewController alloc] init];
if([MFMessageComposeViewController canSendText])
{
controller.body = #"Check out FundooSpace for mobile.Download it now from app.fundoospace.net/FundooSpace/d";
controller.recipients = (NSArray *)passa;
passa = nil;
AppDelegate * appDelegateObject1 = (AppDelegate *)[[UIApplication sharedApplication] delegate];
controller.messageComposeDelegate = self;
[appDelegateObject1.navigationCntr.topViewController presentModalViewController:controller animated:NO];
}
it works fine. but when i click on send or cancel button then app get crash and gives error is
wait_fences: failed to receive reply: 10004003
please suggest me.
I exactly checked the code what you included in your question and for me it is working nicely running on device.
1) make sure to have the delegate in your .h
#interface ViewController : UIViewController <MFMessageComposeViewControllerDelegate>
2) You have to implement the delegate method also in your .m:
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result {
NSLog(#"didFinishWithResult");
// you have to deal with the result var
switch (result) {
case MessageComposeResultCancelled:
NSLog(#"Cancelled");
break;
case MessageComposeResultFailed:
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"MyApp"
message:#"Unknown Error"
delegate:self
cancelButtonTitle:#”OK”
otherButtonTitles:nil];
[alert show];
[alert release];
break;
case MessageComposeResultSent:
break;
default:
break;
}
[self dismissModalViewControllerAnimated:YES];
}
3) if you are on >iOS6.0 the "old" presentModalViewController:animated is deprecated, so change to presentViewController:animated:completion: as Xcode also indicates this.

After sending an in App email with photo attachment the Email window won't dismiss even when I hit send or cancel

I'm in a bit of trouble, I've spent half a day working onto this issue I have with no major results after all deprecations in iOS6 and other issues. This iOS app, has a send email option when after pushing a button, the app takes a screenshot of my WebView, attaches it to the email and from there, have the normal options to cancel or send the email and return to the app. I made it to the part where the email pops up, and actually 2 issues here: one is that after pressing either cancel or send, the email view won't dismiss, the app is stuck in the email view. And the second issue I have is the image that gets attached is just a tiny icon (blue with an question mark just like it is not recognised or is missing...
Can someone please point me in the right direction as I feel like I'm going crazy. I've researched the net backwards and forwards with no luck. Many similar threads but different issues not exactly related to my issues unfortunately. Sorry, and thanks in advance.
Here is my code:
// in my LiveView.h file
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import <MessageUI/MessageUI.h>
#import "CamSetup.h"
#interface LiveView : UIViewController < MFMailComposeViewControllerDelegate , ADBannerViewDelegate >
....
-(IBAction)shotAndSend:(id)sender;
// in my LiveView.m file:
- (void)mailComposer:(MFMailComposeViewController *)controller
didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
NSLog(#"in didFinishWithResult:");
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"cancelled");
break;
case MFMailComposeResultSaved:
NSLog(#"saved");
break;
case MFMailComposeResultSent:
NSLog(#"sent");
break;
case MFMailComposeResultFailed: {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Error sending mail",#"Error sending mail")
message:[error localizedDescription] delegate:nil
cancelButtonTitle:NSLocalizedString(#"test",#"test")
otherButtonTitles:nil];
[alert show];
break;
}
default: break;
}
[self dismissViewControllerAnimated:NO completion:Nil];
}
-(IBAction)shotAndSend:(id)sender
{
UIGraphicsBeginImageContext(_myWebView.frame.size);
[_myWebView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData * imageData = UIImageJPEGRepresentation (image, 2.1);
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController * mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
[mailComposer addAttachmentData:imageData mimeType:#"image/jpeg" fileName:#"attachment.jpeg"];
[mailComposer setSubject:#"A screenshot from my App"];
[mailComposer setToRecipients:[NSArray arrayWithObjects:#"123#yexample.com", nil]];
[self presentViewController: mailComposer animated:YES completion:NULL];
}
}
Your code isn't working because you have the wrong method. You have:
- (void)mailComposer:(MFMailComposeViewController *)controller
didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
but it should be:
- (void)mailComposeController:(MFMailComposeViewController*)controller
didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
You need a delegate of your view that will dismiss that view for you. The fact that you don't see the log indicate you that you haven't implemented correctly the delegation protocol. Take a look at some example in the apple documentation.

Closing a view after cancelling an email

I want to be able to send an email from my app, in which I have got that portion working. The problem is when I cancel sending an email (which is what I'm testing for now) the email part is dismissed but I'm left with a black screen which I can't seem to dismiss.
So this is what I have. I've created a class to handle the email part:
MailViewController.h
#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>
#interface MailViewController : UIViewController <MFMailComposeViewControllerDelegate>
#end
Implemented as follows:
#import "MailViewController.h"
#interface MailViewController ()
#end
#implementation MailViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
if([MFMailComposeViewController canSendMail]){
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
[mailer setMailComposeDelegate:self];
[mailer setSubject:#"Subject"];
NSMutableArray *toArray = [[NSMutableArray alloc] initWithObjects:#"email#gmail.com", nil];
[mailer setToRecipients:toArray];
[self presentViewController:mailer animated:YES completion:nil];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Failuer" message:#"This device is unable to send emails" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error{
switch (result){
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled: you cancelled the operation and no email was sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Mail failed");
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved");
break;
case MFMailComposeResultSent:
NSLog(#"Mail sent");
break;
default:
NSLog(#"Mail not sent");
break;
}
[controller dismissViewControllerAnimated:YES completion:nil];
}
#end
And all of this is shown from another view like so:
-(IBAction)sendMessage:(id)sender{
NSLog(#"Going to send an email....");
MailViewController *mail = [[MailViewController alloc] init];
[self.navigationController pushViewController:mail animated:YES];
}
So when I run all of this, the email program opens and I can do email stuff. I can select Cancel, then Delete Draft and the email program is removed. However, I'm left with a black screen which I can then select Back from the top navigation bar to return to the previous view.
I simply want the app to return to the view that shows the email program when an email is sent or cancelled (or whatever). I'm sure it's something simple I'm missing.
The problem is tat you are pushing a MailViewController and then dimissing, if you push you should pop the view controller.
MFMailComposeViewControllers should be presented modally, not pushed on the navigation stack. You also dont need a subclass, you can create an instance of MFMailComposeViewController directly:
-(IBAction)sendMessage:(id)sender{
NSLog(#"Going to send an email....");
MFMailComposeViewController *mail = [[MFMailComposeViewController alloc] init];
mail.mailComposeDelegate = self;
[self presentViewController:mail animated:YES completion:nil];
}
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error{
switch (result){
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled: you cancelled the operation and no email was sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Mail failed");
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved");
break;
case MFMailComposeResultSent:
NSLog(#"Mail sent");
break;
default:
NSLog(#"Mail not sent");
break;
}
[controller dismissViewControllerAnimated:YES completion:nil];
}
There's a couple architecture questions I have, but first - the TL;DR version:
[self.navigationController popViewControllerAnimated:NO];
You could also choose YES for the boolean, but judging on your implementation, that wouldn't result in something nice. Put that in the delegate call for completion.
However, why not just have whatever's pushing MailViewController onto the stack handle the job of being the MFMailComposeViewControllerDelegate? You're doing nothing here that requires a completely new view controller be pushed onto the stack.

How to add a listener to an MFMessageComposeViewController?

I am trying to send an SMS on an iPhone using MFMessageComposeVieController and I want to add a listener that recognizes when the SMS is sent (in other words, when the user presses "Send"). What is the syntax for this?
For example, I know that with a textField, an example of a listener would be:
[textField addTarget:self action:#selector(methodName) forControlEvents:UIControlEventEditingDidEndOnExit];
Google is very helpful...
Third result is an SMS tutorial.
Relevant code:
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
didFinishWithResult:(MessageComposeResult)result
{
switch (result) {
case MessageComposeResultCancelled:
NSLog(#"Cancelled");
break;
case MessageComposeResultFailed:
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"MyApp"
message:#"Unknown Error"
delegate:self
cancelButtonTitle:#”OK”
otherButtonTitles:nil];
[alert show];
[alert release];
break;
case MessageComposeResultSent:
break;
default:
break;
}
[self dismissModalViewControllerAnimated:YES];
}
Implement the MessageComposeResultSent case to know when the message has been sent.
You want to add a delegate to your MFMessageComposeViewController. In the delegate's messageComposeViewController:didFinishWithResult: method, you can check the result parameter to see whether the user canceled or sent the SMS.
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
didFinishWithResult:(MessageComposeResult)result {
switch(result) {
case MessageComposeResultCancelled:
// user canceled sms
break;
case MessageComposeResultSent:
// user sent sms
break;
case MessageComposeResultFailed:
// sms send failed
break;
default:
break;
}

Using MFMailComposeViewController to send a mail, get “EXC_BAD_ACCESS” when dismissing the modal view controller

I am sending an email from my iPhone app using MFMailComposeViewController. This works fine but after sending or canceling I need to dismiss the modalViewController. When I do this I get a Program received signal: “EXC_BAD_ACCESS”. This is not very descriptive... Please help!!
This is the code for creating the mail and the modalViewController
-(void)sendFavMail:(NSString *)body{
MFMailComposeViewController* mailViewController = [[MFMailComposeViewController alloc] init];
mailViewController.mailComposeDelegate = self;
[mailViewController setSubject:#"Favorites List"];
[mailViewController setMessageBody:body isHTML:YES];
[self presentModalViewController:mailViewController animated:YES];
[mailViewController release];
}
And this is the code for the delegate, dismissing the modalviewcontroller:
- (void)mailComposeController:(MFMailComposeViewController*)controller
didFinishWithResult:(MFMailComposeResult)result
error:(NSError*)error;
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Cancelled sending");
break;
case MFMailComposeResultSaved:
NSLog(#"Message Saved");
break;
case MFMailComposeResultSent:
NSLog(#"Message Sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Sending Failed");
break;
default:
NSLog(#"Message not sent");
break;
}
[self dismissModalViewControllerAnimated:YES];
}
Thanks for your help!!
Darn, fixed it myself :-)
I released an object in the body of the message before sending/cancelling. What I did to fix it is to declare this body object autoreleased. And what do you know? IT WORKS!
Just answered my own question...