使用 SwiftUI 发送电子邮件

Phi*_*rev 3 email messageui ios swift swiftui

我正在尝试在我的迷你应用程序中实现发送电子邮件功能。

这是我正在使用的代码(取自https://hackingwithswift.com):

import Foundation
import SwiftUI
import MessageUI

func sendEmail() {
    if MFMailComposeViewController.canSendMail() {
        let mail = MFMailComposeViewController()
        mail.mailComposeDelegate = self
        mail.setToRecipients(["you@yoursite.com"])
        mail.setMessageBody("<p>You're so awesome!</p>", isHTML: true)

        present(mail, animated: true)
    } else {
        // show failure alert
    }
}

func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    controller.dismiss(animated: true)
}
Run Code Online (Sandbox Code Playgroud)

运行我的代码时,出现以下 2 个错误:

Cannot find self in scope

Cannot find present in scope

我该如何修复它?

Raj*_*han 5

您可以使用UIViewControllerRepresentable

MailComposeViewController

struct MailComposeViewController: UIViewControllerRepresentable {
    
    var toRecipients: [String]
    var mailBody: String
    
    var didFinish: ()->()
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<MailComposeViewController>) -> MFMailComposeViewController {
        
        let mail = MFMailComposeViewController()
        mail.mailComposeDelegate = context.coordinator
        mail.setToRecipients(self.toRecipients)
        mail.setMessageBody(self.mailBody, isHTML: true)
        
        return mail
    }
    
    final class Coordinator: NSObject, MFMailComposeViewControllerDelegate {
        
        var parent: MailComposeViewController
        
        init(_ mailController: MailComposeViewController) {
            self.parent = mailController
        }
        
        func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
            parent.didFinish()
            controller.dismiss(animated: true)
        }
    }
    
    func updateUIViewController(_ uiViewController: MFMailComposeViewController, context: UIViewControllerRepresentableContext<MailComposeViewController>) {
        
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

struct MailView: View {
    @State private var showingMail = false
    
    var body: some View {
        VStack {
            Button("Open Mail") {
                self.showingMail.toggle()
            }
        }
        .sheet(isPresented: $showingMail) {
            MailComposeViewController(toRecipients: ["test@gmail.com"], mailBody: "Here is mail body") {
                // Did finish action
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

可能是另一种解决方案。您可以创建一个单例类并将其呈现MFMailComposeViewController在根控制器上。您可以根据您的要求修改功能。像这样

class MailComposeViewController: UIViewController, MFMailComposeViewControllerDelegate {
    
    static let shared = MailComposeViewController()
    
    func sendEmail() {
        if MFMailComposeViewController.canSendMail() {
            let mail = MFMailComposeViewController()
            mail.mailComposeDelegate = self
            mail.setToRecipients(["you@yoursite.com"])
            mail.setMessageBody("<p>You're so awesome!</p>", isHTML: true)
            UIApplication.shared.windows.first?.rootViewController?.present(mail, animated: true)
        } else {
            // show failure alert
        }
    }
    
    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        controller.dismiss(animated: true)
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

Button(action: {
    MailComposeViewController.shared.sendEmail()
}, label: {
    Text("Send")
})
Run Code Online (Sandbox Code Playgroud)

  • 这是因为模拟器中没有邮件应用程序。 (2认同)