2

I want to send an email from my Swift application and it works well, it sends the email.

Nevertheless, after sending the email, the layout does not quits. I want to quit the layout after sending the email. I also want this behaviour when I press on Cancel, Remove draft or Save draft button.

This is the code that I have to send the email (after pressing a button):

@IBAction func btnSendEmailAction(_ sender: AnyObject) {

    let composeVC = MFMailComposeViewController()
    composeVC.mailComposeDelegate = self

    composeVC.setToRecipients(["mymail@mail.com"])
    composeVC.setSubject("Hello!")
    composeVC.setMessageBody("Hello World!", isHTML: false)

    self.present(composeVC, animated: true, completion: nil)
}

func mailComposeController(controller: MFMailComposeViewController,
                           didFinishWithResult result: MFMailComposeResult, error: NSError?) {

    switch result {

    case MFMailComposeResult.cancelled:
        controller.dismiss(animated: true, completion: nil)
        break

    case MFMailComposeResult.sent:
        controller.dismiss(animated: true, completion: nil)
        break

    case MFMailComposeResult.failed:
        controller.dismiss(animated: true, completion: nil)
        break

    default:
        break
    }

    controller.dismiss(animated: true, completion: nil)
}

but the layout does not quits when I press on Cancel or Sent buttons.

I know that there are a lot of questions related about this problem but I looked a lot of them and this is the code I could get from a mix of some of them. Note that most of them are in Objective instead of Swift (and sometimes the methods does not exist).

Example: iPhone: How to Close MFMailComposeViewController?

Am I missing something on my code? How can I detect Remove draft and Save Draft events?

Thanks in advance!

Community
  • 1
  • 1
Francisco Romero
  • 12,787
  • 22
  • 92
  • 167
  • If you're going to dismiss `controller` in every case, why not take out the switch and just have `controller.dismiss(animated: true, completion: nil)` – Adrian Oct 28 '16 at 13:12
  • @Adrian because it did not dismiss the controller so I tried focussing in each event separately. – Francisco Romero Oct 28 '16 at 13:55
  • @Anish웃 What do you exactly mean? – Francisco Romero Oct 28 '16 at 13:56
  • Do you have `MFMailComposeViewControllerDelegate` in your class declaration or an extension of `YourViewController`? Another thought would be to take out the `break` lines in your `switch`. I'm looking at a working `MFMailComposeController` and I don't have that in there...it works fine of all scenarios. – Adrian Oct 28 '16 at 14:02
  • Yes, I have extended to MFMailComposeViewControllerDelegate. The email works, what I am not able to do is to dismiss the Controller. – Francisco Romero Oct 28 '16 at 14:04

1 Answers1

7

Looks like you're using swift 3 and not using a valid delegate method. Corrected delegate method is this:

func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {

        switch result {
        case .cancelled:
            break
        case .saved:
            break
        case .sent:
            break
        case .failed:
            break

        }

        dismiss(animated: true, completion: nil)
    }
Bhavuk Jain
  • 2,167
  • 1
  • 15
  • 23
  • Ok finally I notice that cancel button on Send draft or Save draft it was to cancel these two options, not the email. Hard Monday. You were right, the delegate method was wrong. Thank you! It works like a charm! – Francisco Romero Oct 31 '16 at 08:26
  • `.dismiss` should be called on the *presenting* view controller not the *presented* view controller. This is unlikely to cause a problem as Apple currently handles this case (and documents that they do), but it makes the code technically incorrect. – Steven Fisher Jul 20 '18 at 01:19
  • 1
    @StevenFisher Thanks for pointing out. I've updated the code. – Bhavuk Jain Jul 21 '18 at 16:55