MFMailComposeViewControllerDelegate not working Swift 3
Asked Answered
D

5

6

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)
}
Doglike answered 4/10, 2016 at 22:10 Comment(0)
J
7

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)

Julejulee answered 9/12, 2016 at 20:21 Comment(1)
If this is really an XCode bug, it still exists in 10.3, when you calculate your attachments on a background thread, and use another view controller for progress, that displays the compose controller at dismiss. But this answer still resolves it, so a big upvote to it!Pressmark
E
3

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)
}
Elevation answered 4/10, 2016 at 22:56 Comment(0)
F
3

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
}
Fax answered 6/12, 2017 at 10:6 Comment(1)
This was about to make my brain explode. So obvious now that I know it! Thank you so much!Media
I
1

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.

Indecorous answered 23/6, 2017 at 1:17 Comment(0)
C
1

Adding

#import <MessageUI/MessageUI.h> 

to the AppName-Bridging-Header.h did the job !

Clinkerbuilt answered 3/9, 2018 at 10:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.