SwiftUI:使用 MFMailComposeViewController 发送电子邮件

SwiftUI: Send email using MFMailComposeViewController

我目前正在尝试在我的 SwiftUI 应用程序中实现“发送电子邮件”按钮,使用 SwiftUI 生命周期并定位 iOS 14.

我知道网上有很多解决方案 - 在此处的堆栈溢出和其他地方。但是,到目前为止,我还无法在 simulator/on 设备上进行任何操作。

我目前的解决方案是这样的(基于这个 :

import SwiftUI
import MessageUI
import Foundation

struct ContentView: View {

    class MailComposeViewController: UIViewController, MFMailComposeViewControllerDelegate {
    
        static let shared = MailComposeViewController()
    
        func sendEmail() {
            if MFMailComposeViewController.canSendMail() {
                let mail = MFMailComposeViewController()
                mail.mailComposeDelegate = self
                mail.setToRecipients(["test@test.com"])

                UIApplication.shared.windows.last?.rootViewController?.present(mail, animated: true, completion: nil)
            } else {
                // Alert
            }
        }
    
        func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
            controller.dismiss(animated: true, completion: nil)
        }
    }
    
    var body: some View {
        Button(action: {
            MailComposeViewController.shared.sendEmail()
        }, label: {
            Text("Send")
        })
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

模拟器确实显示了按钮并且没有给我任何错误。但是,单击按钮后,什么也没有发生——在设备上测试时也是如此。

知道这里可能出了什么问题吗?

谢谢!

您的代码工作正常,问题是 iOS 模拟器没有邮件应用程序,因此 MFMailComposeViewController.canSendMail() returns 错误。在物理设备上试用它,它有效。您没有看到任何错误的原因是因为这段代码:

if MFMailComposeViewController.canSendMail() {
                let mail = MFMailComposeViewController()
                mail.mailComposeDelegate = self
                mail.setToRecipients(["test@test.com"])

                UIApplication.shared.windows.last?.rootViewController?.present(mail, animated: true, completion: nil)
            } else {
                // Alert
            }

else 块内,而不是临时注释 // Alert,你应该在调试时打印一些东西,这会让你的生活更轻松。

在我原来的问题中分享的代码片段的基础上:

根据@Arjun 的回答,这是我当前的解决方法,用于解决可能有人删除了 Apple Mail 应用程序并正在使用其他电子邮件应用程序的极端情况:

Button(action: {
    if MailComposeViewController.shared.thisIsTest() {
        MailComposeViewController.shared.sendEmail()
    } else {
        openURL(URL(string: "mailto:someone@example.com?subject=This%20is%20the%20subject")!)
    }
}, label: {
    Text("Send")
})

只要用户设置了 Apple 邮件,它就会打开应用程序内 sheet,否则会使用 mailto 切换到任何其他电子邮件应用程序:link。