39

I am developing an application,the requirement is to open email composer on a button click of UIAlertView.

message which is in message body of email is copied from UITextView. i am using following code snipt:

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0)
  {
      // opening message composer
  }
else
  {
   MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
    picker.mailComposeDelegate = self;
    [picker setSubject:@"Test mail"];
    [picker setMessageBody:messageBody.text isHTML:YES];
    [self presentViewController:picker animated:YES completion:NULL];
  }
}
 // mail compose delegate
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
      [self dismissViewControllerAnimated:YES completion:NULL];
}

but the issue is that i am getting error saying Application tried to present a nil modal view controller on target. how we can open default mail composer in ios 7?

Bhagyashree mahajan
  • 531
  • 1
  • 6
  • 14

3 Answers3

83

As per Apple, You should check is MFMailComposeViewController are able to send your mail just before sending

if ([MFMailComposeViewController canSendMail]) {
     MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
    picker.mailComposeDelegate = self;
    [picker setSubject:@"Test mail"];
    [picker setMessageBody:messageBody.text isHTML:YES];
    [self presentViewController:picker animated:YES completion:NULL];
}

Swift:

if MFMailComposeViewController.canSendMail() else {
// Send mail code
}

Ref : Apple Dev url


Toseef Khilji
  • 17,192
  • 12
  • 80
  • 121
  • 1
    Guard mechanism rocks! – Naeem Sep 30 '16 at 07:32
  • but why text message (MFMessageComposeViewController) doesn't need this check? I have a testing device that doesn't have sim card, technically it shouldn't be able to send text, but it works fine (no exception thrown) without the check... why? thanks. – RainCast Oct 24 '16 at 21:02
  • So, no more testing the send mail UI on the Simulator...? – Nicolas Miari Nov 02 '16 at 06:48
  • Users' device might have no email account configured. So, testing on simulator can catch the missing guard. After adding `canSendMail`, we'll have to rely on device testing. – John Pang Sep 10 '18 at 09:36
17

Swift 4 version

guard MFMailComposeViewController.canSendMail() else {
    print("Mail services are not available")
    return
}
sendEmail()
rockdaswift
  • 9,613
  • 5
  • 40
  • 46
11

Forgetting Mail account configuration in device settings may also lead to this error. Re check whether a mail account is configured in your device or not.

prodeveloper
  • 943
  • 14
  • 22