Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MFMailComposeViewController crashing while dismissModalViewControllerAnimated in iOS5

I am using MFMailComposeViewController in my conde to provide Mail functionality but after sending mail or when i want to cancel mail it will be crashing.

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:@"[email protected]",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 have read all blog post but no solution is found, This blog post is having good explaination about this but as per this i am not presenting my view controller in viewdidload or viewdidappear.

I'm Getting EXE_BAD_ACCESS, 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 ()

**

As per updated document of apple for ios 5 they mentioned :

presentModalViewController:animated:

Presents a modal view managed by the given view controller to the user. (Deprecated. Use presentViewController:animated:completion: instead.)

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

Dismisses the view controller that was presented by the receiver. (Deprecated. Use dismissViewControllerAnimated:completion: instead.)

- (void)dismissModalViewControllerAnimated:(BOOL)animated

I had tried this also but it still crashes

like image 766
Gaurav Avatar asked Dec 08 '22 22:12

Gaurav


2 Answers

You need to keep a strong reference to MFMailComposeViewController *mailer in your class, and after you dismiss it you can null that reference. Ask me how I know this :-)

@implememtation MyClass
{
    MFMailComposeViewController *mailer;
}
...

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

Later on, when completely done with it, you simply "mailer = nil;" to release it.

EDIT: What I do and suggest is to use a block to the main queue to do the release. If you just use 'self.mailer = nil' then the release happens after the final delegate method has finished and you are for sure no longer using it.

EDIT2: This crash does not happen all the time on all devices - I would say its somewhat of a race condition between when you receive the final delegate method and when its finished its work. Apple does not say anything about holding a reference one way or the other - however, general practice on Apple products is to assume any object you get is "on loan" through one runLoop, and thereafter if you want to keep a reference you have to retain the object.

like image 196
David H Avatar answered Feb 02 '23 00:02

David H


If your are having sharekit framework implemented in your code goto SHK.m and change

        [[currentView parentViewController] dismissModalViewControllerAnimated:YES];

to

        [currentView  dismissModalViewControllerAnimated:YES];

This will solve your problem.

Thanks everyone for response.

and also comment these lines

SHKSwizzle([MFMailComposeViewController class], @selector(viewDidDisappear:), @selector(SHKviewDidDisappear:));
if (NSClassFromString(@"MFMessageComposeViewController") != nil) SHKSwizzle([MFMessageComposeViewController class], @selector(viewDidDisappear:), @selector(SHKviewDidDisappear:));
like image 26
Gaurav Avatar answered Feb 02 '23 00:02

Gaurav