I am currently trying to implement a "send email" button in my SwiftUI app, using SwiftUI lifecycle and targeting iOS 14.
I know there are quite some solutions presented online - here on stack overflow and elsewhere. However, I have-not been able to make anything work so far in simulator/on device.
My current solution looks like this (based on this question on stackoverflow:
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()
}
}
The simulator does show the button and doesn't give me any errors. However, upon clicking the button, nothing happens at all - same thing when testing on device.
Any idea what might be wrong here?
Thanks!
Building up on the code snippet shared in my original question:
Based on the answer from @Arjun this is my current workaround to account for the edge case that someone might have deleted the Apple Mail app and is using another email app:
Button(action: {
if MailComposeViewController.shared.canSendMail() {
MailComposeViewController.shared.sendEmail()
} else {
openURL(URL(string: "mailto:someone@example.com?subject=This%20is%20the%20subject")!)
}
}, label: {
Text("Send")
})
It opens the in-app sheet as long as the user has set up apple mail and otherwise switches to any other email app using a mailto: link.