MFMailComposeViewController 不发送电子邮件或调用委托 (MFMailComposeViewControllerDelegate)

MFMailComposeViewController not sending email or invoking delegate (MFMailComposeViewControllerDelegate)

我有一个 MFMailComposeViewController 设置并显示如下:

class MyViewController: UIViewController {

    // MARK: - Properties
    let composeViewController = MFMailComposeViewController()

    // MARK: - Actions
    @IBAction func didTapSendInEmailButton() {
        composeViewController.mailComposeDelegate = self
        composeViewController.setToRecipients([Constants.contactRecipientEmail])
        composeViewController.setSubject(Constants.contactSubject)
        composeViewController.setMessageBody(Constans.body, isHTML: false)
        present(composeViewController, animated: true, completion: nil)
    }
}

// MARK: - MFMailComposeViewControllerDelegate
extension MyViewController: MFMailComposeViewControllerDelegate {
    private func mailComposeController(_ controller: MFMailComposeViewController,
                                       didFinishWith result: MFMailComposeResult,
                                       error: Error?) {
        switch result {
        case .sent:
            print("Email sent")
        case .saved:
            print("Draft saved")
        case .cancelled:
            print("Email cancelled")
        case  .failed:
            print("Email failed")
        }
        controller.dismiss(animated: true, completion: nil)
    }
}

我遇到了这个问题:

  1. 在 Composer 上按下 "Send" 后,MFMailComposeViewControllerDelegate 不会被调用。

我可能遗漏了什么?

我无法将 mailComposeController 声明为 public:

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

再次检查您的委托方法,它应该是public

还要确保您的邮件帐户配置正确。

不知道你的问题出在哪里

我测试你的代码运行良好,编译器没有强制我将委托设置为 private,请注意电子邮件编辑器不适用于 simulator 仅在 device

import UIKit
import MessageUI
class MyViewController: UIViewController {

    // MARK: - Properties
    let composeViewController = MFMailComposeViewController()

    // MARK: - Actions
    @IBAction func didTapSendInEmailButton() {

        if MFMailComposeViewController.canSendMail() {
            composeViewController.mailComposeDelegate = self
            composeViewController.setToRecipients(["abdela7ad@gmail.com"])
            composeViewController.setSubject("Constants.contactSubjec")
            composeViewController.setMessageBody("Constans.body", isHTML: false)
            present(composeViewController, animated: true, completion: nil)        } else {
        }

    }
}

// MARK: - MFMailComposeViewControllerDelegate
extension MyViewController: MFMailComposeViewControllerDelegate {
    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {

            switch result {
            case .sent:
                print("Email sent")
            case .saved:
                print("Draft saved")
            case .cancelled:
                print("Email cancelled")
            case  .failed:
                print("Email failed")
            }
            controller.dismiss(animated: true, completion: nil)
    }
}

我将在评论中强调的一些小变化:

import UIKit
import MessageUI

class MyViewController: UIViewController {

    // MARK: - Properties
    let composeViewController = MFMailComposeViewController()

    // MARK: - Actions
    @IBAction func didTapSendInEmailButton() {
        composeViewController.mailComposeDelegate = self
        // Entered a generic email in place of your constant value
        composeViewController.setToRecipients(["someone@example.com"])
        // Entered a generic subject in place of your constant value
        composeViewController.setSubject("subject")
        // You have a typo on "Constants" here
        composeViewController.setMessageBody("body", isHTML: false)
        present(composeViewController, animated: true, completion: nil)
    }
}

// MARK: - MFMailComposeViewControllerDelegate
extension MyViewController: MFMailComposeViewControllerDelegate {
    // Removed the private
    func mailComposeController(_ controller: MFMailComposeViewController,
                               didFinishWith result: MFMailComposeResult,
                               error: Error?) {
        switch result {
        case .sent:
            print("Email sent")
        case .saved:
            print("Draft saved")
        case .cancelled:
            print("Email cancelled")
        case  .failed:
            print("Email failed")
        }
        controller.dismiss(animated: true, completion: nil)
    }
}

并且我的控制台日志显示电子邮件已发送

您确认您的 Constants 对象包含有效数据了吗?也许你应该打印出来或者在它到达这里时在断点处查看它以确保它的内容没有问题。

此外,请确保您首先在设备上设置了有效的电子邮件帐户,以便为您发送电子邮件。如果它是一个开发设备,那么它可能在某个时候被重置并丢失了。

比较你的错误类型:

挖矿:

请注意 Error 的颜色发生了变化。这意味着它正在使用您定义的错误,该错误的范围是私有的。您需要通过将错误重命名为其他名称来打破这一点。完成后,它应该可以解决您的错误。

我最近也遇到了类似的问题,我的解决方法是将声明移到按钮操作中

class MyViewController: UIViewController {

    // MARK: - Actions
    @IBAction func didTapSendInEmailButton() {
        let composeViewController = MFMailComposeViewController()
        composeViewController.mailComposeDelegate = self
        composeViewController.setToRecipients([Constants.contactRecipientEmail])
        composeViewController.setSubject(Constants.contactSubject)
        composeViewController.setMessageBody(Constans.body, isHTML: false)
        present(composeViewController, animated: true, completion: nil)
    }
}

// MARK: - MFMailComposeViewControllerDelegate
extension MyViewController: MFMailComposeViewControllerDelegate {
   func mailComposeController(_ controller: MFMailComposeViewController,
                                       didFinishWith result: MFMailComposeResult,
                                       error: Error?) {
        switch result {
        case .sent:
            print("Email sent")
        case .saved:
            print("Draft saved")
        case .cancelled:
            print("Email cancelled")
        case  .failed:
            print("Email failed")
        }
        controller.dismiss(animated: true, completion: nil)
    }
}

此外,您不需要将委托方法设为私有