MailComposer not dismissed

592 Views Asked by At

I tried to use MailComposer. Here is the code I used:

func setupMailer() {
    if MFMailComposeViewController.canSendMail() {
        emailController.mailComposeDelegate = self
        emailController.setToRecipients([]) // set the email address
        emailController.setSubject("BackgroundTask Test")
        emailController.setMessageBody("Message body", isHTML: false)
    }
}

And then when user presses a button:

func buttonPressed(button: UIButton) {
    debugPrint("buttonPressed", button)
    let path = dirpath.appendingPathComponent(filename)
    let data = NSData(contentsOfFile: path.path)
    emailController.mailComposeDelegate = self
    emailController.addAttachmentData(data! as Data, mimeType: "text/csv", fileName: filename)
    present(emailController, animated: true, completion: nil)
}

And when dismiss:

@objc func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    debugPrint("mailComposeController dismiss")
    controller.dismiss(animated: true, completion: nil)
}

It is found that if the button is pressed for the first time, the mail composer works normally no matter I choose send or cancel.

However, after I send/cancel, for the 2nd time onwards, the mail composer cannot be dismissed. The send has response that can send the email, but the mail composer interface never dismiss.

I found that the function func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) is not triggered any more after the first time.

Any clues?

3

There are 3 best solutions below

1
Bilal On BEST ANSWER

You are not supposed to use the same MFMailComposeViewController instance again..

Try this

func setupMailer() {
    if MFMailComposeViewController.canSendMail() {
        emailController = MFMailComposeViewController.init()
        emailController.mailComposeDelegate = self
        emailController.setToRecipients([]) // set the email address
        emailController.setSubject("BackgroundTask Test")
        emailController.setMessageBody("Message body", isHTML: false)
    }
}
0
Anmol On

Well don't know what you're doing wrong. I think you're using Swift. So I will explain you how can you implement that. Steps:

1) import MessagesUI and add delegate MFMailComposeViewControllerDelegate

2) Add this function:

func configuredMailComposeViewController() -> MFMailComposeViewController {
    let mailComposerVC = MFMailComposeViewController()
    mailComposerVC.mailComposeDelegate = self
    mailComposerVC.setToRecipients(["[email protected]"])
    mailComposerVC.setSubject("Sending you an in-app e-mail...")
    mailComposerVC.setMessageBody("Sending e-mail in-app is not so bad!", isHTML: false)

    return mailComposerVC
}

3) Call the above function in IBAction of button as:

let mailComposeViewController = configuredMailComposeViewController()
    if MFMailComposeViewController.canSendMail() {
        self.present(mailComposeViewController, animated: true, completion: nil)
    } else {
        // Show alert if user can't send mail
    }

4) Lastly implement delegate method:

func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    controller.dismiss(animated: true, completion: nil)
}
0
user6539552 On

Right, the point is that I reuse the emailController instance.

  func setupMailer() {
if MFMailComposeViewController.canSendMail() {
  emailController = MFMailComposeViewController()
  emailController.mailComposeDelegate = self
  emailController.setToRecipients([]) // set the email address
  emailController.setSubject("BackgroundTask Test")
  emailController.setMessageBody("Message body", isHTML: false)
}

}

  func buttonPressed(button: UIButton) {
    debugPrint("buttonPressed", button)
    let path = dirpath.appendingPathComponent(filename)
    let data = NSData(contentsOfFile: path.path)
    setupMailer()
    emailController.addAttachmentData(data! as Data, mimeType: "text/csv", fileName: filename)
    present(emailController, animated: true, completion: nil)
  }

  @objc func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    debugPrint("mailComposeController dismiss")
    controller.dismiss(animated: true, completion: nil)
  }

This works now.