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。
我目前正在尝试在我的 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。