MFMailComposeViewController crashes while rejectModalViewControllerAnimated in iOS5

I use MFMailComposeViewController in my conde to provide Mail functionality, but after sending mail or when I want to cancel mail, it will fail.

below is my code:

(IBAction)FnForPlutoSupportEmailButtonPressed:(id)sender { { if ([MFMailComposeViewController canSendMail]) { MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init]; mailer.mailComposeDelegate = self; [mailer setSubject:@"Need help from Pluto support team"]; NSArray *toRecipients = [NSArray arrayWithObjects:@" support@myplu.to ",nil]; [mailer setToRecipients:toRecipients]; NSString *emailBody = @""; [mailer setMessageBody:emailBody isHTML:NO]; //mailer.modalPresentationStyle = UIModalPresentationPageSheet; [self presentModalViewController:mailer animated:YES]; } else { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Failure" message:@"Your device doesn't support the composer sheet" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; [alert show]; } } } (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error { // Notifies users about errors associated with the interface switch (result) { case MFMailComposeResultCancelled: break; case MFMailComposeResultSaved: break; case MFMailComposeResultSent: break; case MFMailComposeResultFailed: break; default: break; } [self dismissModalViewControllerAnimated:YES]; } 

I read all the blog posts, but no solution was found. This blog post has a good explanation about this, but according to this, I am not presenting my view controller in viewdidload or viewdidappear.

I get EXE_BAD_ACCESS, The following is the crash log:

**

 > #0 0x00000000 in ?? () > #1 0x01dc5aa4 in -[UIViewController _setViewAppearState:isAnimating:] () > #2 0x01dc5f47 in -[UIViewController __viewDidDisappear:] () > #3 0x01dc6039 in -[UIViewController _endAppearanceTransition:] () > #4 0x01dd2e7e in -[UIViewController(UIContainerViewControllerProtectedMethods) endAppearanceTransition] () > #5 0x01fc8de1 in -[UIWindowController transitionViewDidComplete:fromView:toView:] () > #6 0x01da334b in -[UITransitionView notifyDidCompleteTransition:] () > #7 0x01da3070 in -[UITransitionView _didCompleteTransition:] () > #8 0x01da531b in -[UITransitionView _transitionDidStop:finished:] () > #9 0x01d23fb6 in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] () > #10 0x01d24154 in -[UIViewAnimationState animationDidStop:finished:] () > #11 0x0163bbce in CA::Layer::run_animation_callbacks () > #12 0x03664fe4 in _dispatch_client_callout () > #13 0x03655997 in _dispatch_main_queue_callback_4CF () > #14 0x012c03b5 in __CFRunLoopRun () > #15 0x012bf804 in CFRunLoopRunSpecific () > #16 0x012bf6db in CFRunLoopRunInMode () > #17 0x030f1913 in GSEventRunModal () > #18 0x030f1798 in GSEventRun () > #19 0x01ce82c1 in UIApplicationMain () 

**

According to the updated apple for ios 5 doc, they mentioned:

presentModalViewController: animated:

Represents a modal view controlled by this presentation controller to the user. (Using presentViewController:animated:completion: not recommended.)

 - (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated Parameters 

Disables the view controller that was presented by the receiver. (Using dismissViewControllerAnimated:completion: not recommended.)

 - (void)dismissModalViewControllerAnimated:(BOOL)animated 

I tried this too, but it fails anyway

+4
source share
7 answers

If you have a sharekit framework implemented in your goto SHK.m code and change

  [[currentView parentViewController] dismissModalViewControllerAnimated:YES]; 

to

  [currentView dismissModalViewControllerAnimated:YES]; 

This will solve your problem.

Thanks to everyone for the answer.

and also comment on these lines

 SHKSwizzle([MFMailComposeViewController class], @selector(viewDidDisappear:), @selector(SHKviewDidDisappear:)); if (NSClassFromString(@"MFMessageComposeViewController") != nil) SHKSwizzle([MFMessageComposeViewController class], @selector(viewDidDisappear:), @selector(SHKviewDidDisappear:)); 
+3
source

You need to keep the link to the MFMailComposeViewController * email program in your class, and after removing it, you can specify this link. Ask me how I know this :-)

 @implememtation MyClass { MFMailComposeViewController *mailer; } ... (IBAction)FnForPlutoSupportEmailButtonPressed:(id)sender { { if ([MFMailComposeViewController canSendMail]) { /* USE IVAR */mailer = [[MFMailComposeViewController alloc] init]; 

Later, when this is fully done, you simply "mailer = nil;" to free him.

EDIT: what am I doing and suggest using a block for the main queue for release. If you just use "self.mailer = nil", then the release occurs after the final delegation method is completed, and you will no longer use it.

EDIT2: This crash does not always happen on all devices - I would say that it’s kind of like a race condition between when you get the final delegation method and when it has finished its work. Apple doesn’t say anything about linking anyway, however, the general practice of Apple products is to assume that any object you receive is “on credit” through one runLoop, and then if you want to keep the link you must save the object.

+4
source

HI you can use the following code to send mail, the application will not send any email simulator that you must install on your device. EXE_BAD_ACCESS appears when you try to access an object that is not in memory, and the device of the repeater is case sensitive.

 -(void)sendMail:(id)sender { //create instance of class at runtime. Class mailComposer = (NSClassFromString(@"MFMailComposeViewController")); if (mailClass != nil) { // check the current device is configured for sending emails //if it is not configured for mail you open mail application on device. if ([mailClass canSendMail]) { [self displayComposerSheet]; } else { [self launchMailAppOnDevice]; } } else { [self launchMailAppOnDevice]; } } -(void)displayComposerSheet { MFMailComposeViewController *mailPicker = [[MFMailComposeViewController alloc] init]; picker.mailComposeDelegate = self; [picker setSubject:@"Welcome!"]; //recipients NSArray *to = [NSArray arrayWithObject:@" jhon@example.com "]; [picker setToRecipients:toRecipients]; // Attach an image NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Default" ofType:@"png"]; NSData *imageData = [NSData dataWithContentsOfFile:filePath]; [picker addAttachmentData:myData mimeType:@"image/png" fileName:@"Default"]; // Set email body text //NSString *emailBody = @"......!"; //[picker setMessageBody:emailBody isHTML:NO]; [self presentModalViewController:picker animated:YES]; [picker release]; } - (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult: (MFMailComposeResult)result error:(NSError*)error { message.hidden = NO; // Notifies users about errors associated with the interface switch (result) { case MFMailComposeResultCancelled: message.text = @"Canceled"; break; case MFMailComposeResultSaved: message.text = @"Saved"; break; case MFMailComposeResultSent: message.text = @"Sent"; break; case MFMailComposeResultFailed: message.text = @"Failed"; break; default: message.text = @"Not sent"; break; } [self dismissModalViewControllerAnimated:YES]; } -(void)launchMailAppOnDevice { NSString *recipients = @""; NSString *body = @""; NSString *email1 = [NSString stringWithFormat:@"%@%@", recipients, body]; email1 = [email1 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; [[UIApplication sharedApplication] openURL:[NSURL URLWithString:email1]]; } 
+2
source

Since the stack stop is 0x00000000 , I assume that the code inside UIKit jumps to the nil function pointer. Turn on Zombies and see if you have an error accessing the zombie object. (Change the project scheme, in the section "Run / Debug", "Diagnostics", check the box "Enable zombie objects")

+2
source

try this code, it works well without crashing .. contact us method button target selector ..

  -(void)ContactUs:(UIButton*)button { Class mailClass = (NSClassFromString(@"MFMailComposeViewController")); if (mailClass != nil) { // We must always check whether the current device is configured for sending emails if ([mailClass canSendMail]) { [self displayComposerSheet]; } else { [self launchMailAppOnDevice]; } } else { [self launchMailAppOnDevice]; } } -(void)displayComposerSheet { MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init]; picker.mailComposeDelegate = self; //[picker setSubject:@"Hello from California!"]; // Set up recipients NSArray *toRecipients = [NSArray arrayWithObject:@" info@imp.co.in "]; //NSArray *ccRecipients = [NSArray arrayWithObjects:@" second@example.com ", @" third@example.com ", nil]; //NSArray *bccRecipients = [NSArray arrayWithObject:@" fourth@example.com "]; [picker setToRecipients:toRecipients]; //[picker setCcRecipients:ccRecipients]; //[picker setBccRecipients:bccRecipients]; // Attach an image to the email /*NSString *path = [[NSBundle mainBundle] pathForResource:@"rainy" ofType:@"png"]; NSData *myData = [NSData dataWithContentsOfFile:path]; [picker addAttachmentData:myData mimeType:@"image/png" fileName:@"rainy"];*/ // Fill out the email body text //NSString *emailBody = @"It is raining in sunny California!"; //[picker setMessageBody:emailBody isHTML:NO]; [self presentModalViewController:picker animated:YES]; [picker release]; } - (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error { message.hidden = NO; // Notifies users about errors associated with the interface switch (result) { case MFMailComposeResultCancelled: message.text = @"Canceled"; break; case MFMailComposeResultSaved: message.text = @"Saved"; break; case MFMailComposeResultSent: message.text = @"Sent"; break; case MFMailComposeResultFailed: message.text = @"Failed"; break; default: message.text = @"Not sent"; break; } [self dismissModalViewControllerAnimated:YES]; } -(void)launchMailAppOnDevice { NSString *recipients = @""; NSString *body = @""; NSString *email1 = [NSString stringWithFormat:@"%@%@", recipients, body]; email1 = [email1 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; [[UIApplication sharedApplication] openURL:[NSURL URLWithString:email1]]; } 
+1
source

If you use ARC, the controller object will be released before you call the dismissal.

Save the object somewhere other than the variable selected by the stack.

+1
source

Have you installed the MFMailComposeViewControllerDelegate delegate in the .h file. I have encountered such a problem in the past. And the error was very minor. Please check the delegate in the .h file.

0
source

All Articles