swiftmessageui

MFMailComposeViewControllerDelegate not being called in other class swift 4


I have this code the problem its about didFinishWith result doesn't called and the app crashes. This is my code

Note: In Objective C this code works fine because I create a strong reference in my class but I have a problem in Swift and I dont know how to solve this

import Foundation
import MessageUI

class EmailCreator: NSObject, MFMailComposeViewControllerDelegate {
    // in other class I send this var to show email
    var viewToShow = UIViewController ()

    func sendEmail() {

        let mailComposeViewController = createMailComposeViewController()
        if MFMailComposeViewController.canSendMail(){
            viewToShow.present(mailComposeViewController, animated: true, completion: nil)
        }else{
            print("Can't send email")
        }
    }

    func createMailComposeViewController() -> MFMailComposeViewController {
        let mailComposeViewController = MFMailComposeViewController()
        mailComposeViewController.mailComposeDelegate = self
        mailComposeViewController.setToRecipients(["example@test.test"])
        mailComposeViewController.setSubject("subject")
        mailComposeViewController.setMessageBody("test body", isHTML: false)
        return mailComposeViewController
    }
    //MARK: - MFMail compose method
    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        controller.dismiss(animated: true, completion: nil)
    }
}

And here in other class I have this code to show the email:

@IBAction func sendEmail(_ sender: UIButton) {

        let email = EmailCreator()
        email.viewToShow = self
        email.sendEmail()
}

Solution

  • It crashes because you have the EmailCreator, a local var the delegate of MFMailComposeViewController as shown in your func createMailComposeViewController. By the time MFMailComposeViewController calls the didFinishWith method the EmailCreator is already deinited. You can fix this by making your EmailCreator instance a strong property.

    YourViewController: UIViewController {
        let email = EmailCreator()
    
         @IBAction func sendEmail(_ sender: UIButton) {
            email.viewToShow = self
            email.sendEmail()
        }
    }