Swift 如何从类邮件中删除MFMailComposeViewController?

Swift 如何从类邮件中删除MFMailComposeViewController?,swift,mfmailcomposeviewcontroller,Swift,Mfmailcomposeviewcontroller,我已将邮件函数从UIviewController中分离出来,并将它们放入一个类“mail”中。工作正常,但现在我很难关闭我的“MFMailComposeViewController”。代理“MailComposecController”未被调用,您知道如何修复吗 import Foundation import MessageUI class Mail: UIViewController, MFMailComposeViewControllerDelegate{ static fu

我已将邮件函数从UIviewController中分离出来,并将它们放入一个类“mail”中。工作正常,但现在我很难关闭我的“MFMailComposeViewController”。代理“MailComposecController”未被调用,您知道如何修复吗

import Foundation
import MessageUI


class Mail: UIViewController, MFMailComposeViewControllerDelegate{

    static func createMail2(
        fromViewController:UIViewController,
        recipients  :String,
        messageTitle:String,
        messageText :String,
        attachment  :AnyObject?)
    {

        
        if MFMailComposeViewController.canSendMail() {
            let mail = MFMailComposeViewController()
            //mail.mailComposeDelegate = self //Cannot assign value of type 'Mail.Type' to type 'MFMailComposeViewControllerDelegate?'
            mail.mailComposeDelegate? = fromViewController as! MFMailComposeViewControllerDelegate //added ? (optional)
            

            mail.setToRecipients([recipients])   //(["mail@to.me"])
            mail.setSubject(messageTitle)        //("your subject text")
            mail.setMessageBody(messageText, isHTML: false)
            
            //ggf. Attachment beifügen>>>
            if attachment != nil {
                //attachment vorhanden, also anhängen
                
                let attachName = "\(messageTitle).pdf"
                
                mail.addAttachmentData(
                    attachment as! Data,
                    mimeType: "application/octet-stream", //für binäre Daten, funktioniert immer
                    fileName: attachName)
            }//end if attachment
            //<<<ggf. Attachment beifügen

            
            // Present the view controller modally
            fromViewController.present(mail, animated: true)  //show mail
        } else {
            // show failure alert
            print("Mail services are not available")
            
            let alert = UIAlertController(title: "Mail error", message: "Your device has not been configured to send e-mails", preferredStyle: .alert)
            let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
            alert.addAction(okAction)
            fromViewController.present(alert,animated: true, completion: nil)
        }//end if else
    }//end func createMail
    
    
    //mail delegate
    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        //It’s called when the user dismisses the controller, either by sending the email or canceling the action. Either way, you have to dismiss the controller manually.
        
        //ggf. noch aktionen...
        
        controller.dismiss(animated: true) //remove the mail view
    }//end func mailComposeController
}//end class Mail
<代码>导入基础 导入消息用户界面 类邮件:UIViewController、MFMailComposeViewController和Elegate{ 静态函数createMail2( fromViewController:UIViewController, 收件人:字符串, messageTitle:String, messageText:String, 附件:AnyObject?) { 如果MFMailComposeViewController.canSendMail(){ 让mail=MFMailComposeViewController() //mail.mailComposeDelegate=self//无法将“mail.type”类型的值分配给“MFMailComposeViewControllerDelegate”类型 mail.mailComposeDelegate?=fromViewController as!MFMailComposeViewControllerDelegate//已添加?(可选) mail.setToRecipients([recipients])/([”mail@to.me"]) mail.setSubject(messageTitle)/(“您的主题文本”) setMessageBody(messageText,isHTML:false) //ggf.附件beifügen>>> 如果附件!=无{ //附件vorhanden,也叫anhängen 让attachName=“\(messageTitle).pdf” mail.addAttachmentData( 附件为!数据, mimeType:“应用程序/八位字节流”,//für binäre Daten,funktioniert immer 文件名:attachName) }//如果是附件,则结束
// 作为ViewController的
参数传递的
UIViewController
应符合
MFMailComposeViewControllerDelegate
协议,并且您应在该控制器的定义中实现
mailComposeController(u:didFinishWith:

class Mail: UIViewController {

    static func createMail2(
        fromViewController: UIViewController,
        recipients  :String,
        messageTitle:String,
        messageText :String,
        attachment  :AnyObject?) {

        if MFMailComposeViewController.canSendMail() {
            let mail = MFMailComposeViewController()
            if let fromViewController = fromViewController as? MFMailComposeViewControllerDelegate {
                mail.mailComposeDelegate = fromViewController
            } else {
                print("fromViewController needs to conform to MFMailComposeViewControllerDelegate")
            }
            //...
        }
    }
}

作为ViewController
参数传递的
UIViewController
应符合
MFMailComposeViewControllerDelegate
协议,并且您应在该控制器的定义中实现
mailComposeController(u:didFinishWith:

class Mail: UIViewController {

    static func createMail2(
        fromViewController: UIViewController,
        recipients  :String,
        messageTitle:String,
        messageText :String,
        attachment  :AnyObject?) {

        if MFMailComposeViewController.canSendMail() {
            let mail = MFMailComposeViewController()
            if let fromViewController = fromViewController as? MFMailComposeViewControllerDelegate {
                mail.mailComposeDelegate = fromViewController
            } else {
                print("fromViewController needs to conform to MFMailComposeViewControllerDelegate")
            }
            //...
        }
    }
}

您需要创建邮件控制器的静态共享实例,并将if设置为mailComposeDelegate。您还应该在邮件控制器中创建控制器属性,以保留调用邮件生成器的视图控制器的引用,并将createMail声明为实例方法(非静态):


用法:

class ViewController: UIViewController {
    override func viewDidLoad() {
           super.viewDidLoad()
    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let recipients = "user@email.com"
        let messageTitle = "New Message"
        let messageText = "Mail Test"
        MailComposer.shared.compose(controller: self, recipients: recipients, messageTitle: messageTitle, messageText: messageText)
    }
}

您需要创建邮件控制器的静态共享实例,并将if设置为mailComposeDelegate。您还应该在邮件控制器中创建控制器属性,以保留调用邮件生成器的视图控制器的引用,并将createMail声明为实例方法(非静态):


用法:

class ViewController: UIViewController {
    override func viewDidLoad() {
           super.viewDidLoad()
    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let recipients = "user@email.com"
        let messageTitle = "New Message"
        let messageText = "Mail Test"
        MailComposer.shared.compose(controller: self, recipients: recipients, messageTitle: messageTitle, messageText: messageText)
    }
}

我最近也遇到了同样的问题。答案是:这是一个高度复杂的解决方案。对我来说,Leo的答案是一个更轻量级的解决方案,适合我的需要。非常感谢您的回答。非常欢迎。我最近也遇到了同样的问题。答案是:这是一个高度复杂的解决方案。对我来说,Leo的答案是一个更轻量级的解决方案适合我的需要。非常感谢您的回答。非常欢迎。基于Leo Dabus评论的解决方案。此解决方案的优点是将所有代码保留在Mail类中。我不需要在调用VC中添加扩展,使其符合“MFMailComposeViewControllerDelegate”协议。这一切都在这里,没有冗余代码我也尝试了弗兰肯斯坦的解决方案。它工作得很好,而且更容易实现。正如为避免代码冗余所解释的,我选择了Leo Dabus解决方案。非常感谢您的帮助。嗨,Leo,在您的示例用法中,它应该是:
Mail.shared.createMail(控制器:自身,收件人:收件人,messageTitle:messageTitle,messageText:messageText)
@RvdH不客气。我已经编辑并添加了真实的代码。不需要对UIViewController进行子类化。基于Leo Dabus注释的解决方案。此解决方案的优点是将所有代码保留在Mail类中。我不需要在调用VC中添加扩展,使其符合“MFMailComposeViewController”协议。我在不同的VC中都没有冗余代码。我也尝试了弗兰肯斯坦的解决方案。它运行良好,易于实现。正如为避免代码冗余所解释的,我选择了Leo Dabus解决方案。非常感谢您的帮助。嗨,Leo,在您的示例用法中,它应该是:
Mail.shared.createMail(controller:self,recipients:recipients,messageTitle:messageTitle,messageText:messageText)
@RvdH不客气。我已经编辑并添加了真实的代码。不需要将UIViewController子类化。