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)
}
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)
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)
}
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
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With