views:

1266

answers:

2

It's one of the simplest things to do, I know. But I've been banging my head against this for days. I've done it plenty of times in the past, but for some reason trying to present a modal view controller just crashes the app to a black screen. Nothing reported in the console or anything. I'm hoping someone might have had this problem and has some advice.

This code is called from a UIViewController class:

MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:@"test subject"];
[controller setMessageBody:@"this is the message body" isHTML:NO];
[self presentModalViewController:controller animated:YES];
A: 

As Andrew has pointed out in his comment, do you check

+[MFMailComposeViewController canSendMail]

before trying to push the view controller? The behavior of the MFMailComposeViewController is not well defined if this method returns NO (which may also well be the case when running on the simulator, though I'm not sure). From the documentation:

Before using this class, you must always check to see if the current device is configured to send email at all using the canSendMail method. If the user’s device is not set up for the delivery of email, you can notify the user or simply disable the email dispatch features in your application. You should not attempt to use this interface if the canSendMail method returns NO.

Have you tried to push another view controller instead? Does this crash your app, too?

Daniel Rinser
Check this out:UIViewController *tester = [[UIViewController alloc] initWithNibName:@"TestNib" bundle:nil]; [self presentModalViewController:tester animated:YES];It crashes!
sol
+1  A: 

Hi Are you showing another modal view controller before trying to show MFMailComposeViewController? I had the same problem and found a workaround:

- (void)peopleMultiPickerNavigationController:(PeopleMultiPickerNavigationController *)peoplePicker 
              didSelectContacts:(NSArray *)contacts {

[self dismissModalViewControllerAnimated:YES];

// some more code here

[self performSelector:@selector(sendEmail) withObject:nil afterDelay:0.45]; // this works only if delay > ~0.4!
// [self sendEmail]; // this won't work

// some more code here

}

- (void) sendEmail {
  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:emails];
    } else {
      [self launchMailAppOnDevice:emails];
    }
  } else {
    [self launchMailAppOnDevice:emails];
  } 
}

I know it's an ugly workaround, but I didn't found anything better :(