In iOS development, sending emails directly from your app can enhance user interaction by providing a seamless experience for sharing information or contacting support. In this tutorial, we’ll explore how to integrate MFMailComposeViewController
with SwiftUI to allow users to compose and send emails from within your app.
SwiftUI View
We will create a SwiftUI view that conforms to UIViewControllerRepresentable
to wrap around MFMailComposeViewController
. After sending an email, we will use an @Environment(.dismiss)
action to dismiss the controller.
import SwiftUI
import MessageUI
public struct MailComposeView: UIViewControllerRepresentable {
let subject: String
let toRecipients: [String]
let body: String
@Environment(\.dismiss) private var dismiss
public static var canSendMail: Bool {
MFMailComposeViewController.canSendMail()
}
public init(subject: String, toRecipients: [String], body: String) {
self.subject = subject
self.toRecipients = toRecipients
self.body = body
}
public func makeUIViewController(context: Context) -> MFMailComposeViewController {
let controller = MFMailComposeViewController()
controller.setSubject(subject)
controller.setToRecipients(toRecipients)
controller.setMessageBody(body, isHTML: false)
controller.mailComposeDelegate = context.coordinator
return controller
}
public func updateUIViewController(_ uiViewController: MFMailComposeViewController, context: Context) {}
public func makeCoordinator() -> Coordinator {
Coordinator {
dismiss()
}
}
public class Coordinator: NSObject, MFMailComposeViewControllerDelegate {
private var dismiss: () -> Void
init(dismiss: @escaping () -> Void) {
self.dismiss = dismiss
}
public func mailComposeController(
_ controller: MFMailComposeViewController,
didFinishWith result: MFMailComposeResult,
error: Error?
) {
dismiss()
}
}
}
Example of usage
You can present this view modally within your app.
import SwiftUI
public struct FeedbackDemoView: View {
@State private var isFeedbackPresented = false
public var body: some View {
Button("Feedback") {
isFeedbackPresented.toggle()
}
.fullScreenCover(isPresented: $isFeedbackPresented) {
feedbackView
}
}
@ViewBuilder
private var feedbackView: some View {
if MailComposeView.canSendMail {
MailComposeView(
subject: "Feedback",
toRecipients: ["livsy@livsycode.com"],
body: ""
)
} else {
NavigationStack {
ContentUnavailableView(
"The Mail application is not configured.",
systemImage: "exclamationmark.bubble",
description: Text("")
)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cancel") {
isFeedbackPresented = false
}
}
}
}
}
}
}
Conclusion
By using MFMailComposeViewController
within SwiftUI, you’ve added a powerful feature to your app with minimal code.
If you enjoyed this article, please feel free to follow me on my social media: