Как удалить MFMailComposeViewController из классной почты? - PullRequest
0 голосов
/ 08 июля 2020

Я отделил почтовые функции от своего UIviewController и поместил их в класс Mail. Работает нормально, но теперь у меня проблемы с тем, чтобы закрыть мой «MFMailComposeViewController». Делегат mailComposeController не вызывается. Есть идеи, как исправить?

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

Ответы [ 2 ]

1 голос
/ 09 июля 2020

Что вам нужно, так это создать stati c общий экземпляр вашего почтового контроллера и установить его как mailComposeDelegate. Вы также должны создать свойство контроллера в своем почтовом контроллере, чтобы сохранить ссылку на контроллер представления, который вызвал почту composer, и объявить ваш createMail как метод экземпляра (не stati c):

import UIKit
import MessageUI

class MailComposer: NSObject, MFMailComposeViewControllerDelegate {
    static let shared = MailComposer()
    private var controller: UIViewController?
    func compose(controller: UIViewController, recipients: String,
                 messageTitle: String, messageText: String, fileURL: URL? = nil) { //, completion: @escaping ((MFMailComposeResult, Error?) -> Void)) {
        self.controller = controller
        if MFMailComposeViewController.canSendMail() {
            let mail = MFMailComposeViewController()
            mail.mailComposeDelegate = MailComposer.shared
            mail.setToRecipients([recipients])
            mail.setSubject(messageTitle)
            mail.setMessageBody(messageText, isHTML: false)
            if let fileURL = fileURL {
                do {
                    try mail.addAttachmentData(Data(contentsOf: fileURL), mimeType: "application/octet-stream", fileName: fileURL.lastPathComponent)
                } catch {
                    print(error)
                }
            }
            controller.present(mail, animated: true)
        } else {
            let alertController = UIAlertController(title: "Mail Compose Error",
                message: "Your device has not been configured to send e-mails",
                preferredStyle: .alert)
            alertController.addAction(.init(title: "OK", style: .default) { _ in
                alertController.dismiss(animated: true)
            })
            controller.present(alertController, animated: true)
        }
    }
    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        // You should switch the result only after dismissing the controller
        controller.dismiss(animated: true) {
            let message: String
            switch result {
            case .sent: message = "Message successfully sent!"
            case .saved: message = "Message saved!"
            case .cancelled: message = "Message Canceled!"
            case .failed:  message = "Unknown Error!"
            @unknown default: fatalError()
            }
            let alertController = UIAlertController(title: "Mail Composer",
                message: message,
                preferredStyle: .alert)
            alertController.addAction(.init(title: "OK", style: .default) { _ in
                alertController.dismiss(animated: true)
            })
            self.controller?.present(alertController, animated: true) {
                self.controller = nil
            }
            
        }
    }
}

Использование:

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)
    }
}
1 голос
/ 08 июля 2020

UIViewController, который вы передаете в качестве параметра для fromViewController, должен соответствовать протоколу MFMailComposeViewControllerDelegate, и вы должны реализовать mailComposeController(_: 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")
            }
            //...
        }
    }
}
...