Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MFMailComposeViewControllerDelegate not working Swift 3

I have been using the mail composer in a few of my apps for awhile now and as of recent the mailComposeDelegate no longer gets call.
I wasn't sure if this was something to do with the new release of Swift.
So, I thought I would ask and see if anyone else is having similar issues.
I can present the mail composer but it never gets dismissed due to the delegate not working.

Below is an exact copy of the code I have been using:

func launchFeedback() {
    guard MFMailComposeViewController.canSendMail() else {
        return
    }

    let emailTitle = "Feedback"
    let messageBody = ""
    let toRecipents = ["[email protected]"]
    mailComposer.mailComposeDelegate = self
    mailComposer.setSubject(emailTitle)
    mailComposer.setMessageBody(messageBody, isHTML: false)
    mailComposer.setToRecipients(toRecipents)
    self.show(mailComposer, sender: self)
}

func mailComposeController(controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    print(error)
    controller.dismiss(animated: true, completion: nil)
}
like image 681
bevbomb Avatar asked Oct 04 '16 22:10

bevbomb


4 Answers

This is clearly an Xcode bug. The only way to get around this (after searching though StackOverflow life for an hour) was this:

    @objc(mailComposeController:didFinishWithResult:error:)
    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult,error: NSError?) {
        controller.dismiss(animated: true)
    }

See the @objc macro before the method implementation. Also note that the last parameter has to be NSError type instead of Error as suggested by Apple documentation (and autocompleted by Xcode)

like image 84
videolist Avatar answered Oct 21 '22 20:10

videolist


Swift 3 no longer has unnamed first parameters by default (see this proposal), so you'll need to add an underscore to your function:

func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    print(error)
    controller.dismiss(animated: true, completion: nil)
}
like image 25
Deyton Avatar answered Oct 21 '22 22:10

Deyton


Swift 4, Xcode 9.1. My issue was that MFMailComposeViewController was working fine but if you click cancel, dismiss, and then trying to open it one more time both cancel and send button will not fire didFinishWith delegate function. It was happening because I've declared MFMailComposeViewController as lazy variable and solution was to create new instance of MFMailComposeViewController every time you want to open it.

Problem:

lazy var mailComposeViewController: MFMailComposeViewController = {
    let mailComposeViewController = MFMailComposeViewController()
    mailComposeViewController.mailComposeDelegate = self
    mailComposeViewController.setToRecipients(["[email protected]"])
    mailComposeViewController.setSubject("subject")
    mailComposeViewController.setMessageBody("test body", isHTML: false)
    return mailComposeViewController
}()

Solution:

func createMailComposeViewController() -> MFMailComposeViewController {
    let mailComposeViewController = MFMailComposeViewController()
    mailComposeViewController.mailComposeDelegate = self
    mailComposeViewController.setToRecipients(["[email protected]"])
    mailComposeViewController.setSubject("subject")
    mailComposeViewController.setMessageBody("test body", isHTML: false)
    return mailComposeViewController
}
like image 3
mkz Avatar answered Oct 21 '22 22:10

mkz


After wasting 2 good hours, i came to the conclusion that as of Xcode 8.3. MFMailComposeViewController does not work on a mixed swift/objc code base. It pops odd compile errors, which first i thought were due to my stupidity, but no.

This is so frustrating apple. Most of us old timers do have tons of code on obj-c, so a pure swift scenario is close to impossible. So as i move classes to swift i have to deal with extra pain as well.

like image 1
Klajd Deda Avatar answered Oct 21 '22 22:10

Klajd Deda