Mastering Email Functionality in SwiftUI Applications
Written on
Introduction to Email in SwiftUI
In today's technology-driven world, email serves as a vital means of communication, effectively linking users across the globe. This guide is designed for developers at any level, providing a straightforward approach to setting up email composition and sending within your SwiftUI application.
In this article, we will delve into how to send emails using SwiftUI, covering both scenarios with and without attachments.
How to Send Email in SwiftUI
We will structure our code into a mail helper class and a basic SwiftUI interface. The mail helper class will utilize MFMailComposeViewController to launch the native mail application, pre-filling the Subject, Body, and To fields. The SwiftUI view will feature three text fields for entering the Subject, To, and Body of the email.
Creating the MailHelper in SwiftUI
Our MailHelper class will be relatively straightforward, encompassing three functions: sendEmail, getRootViewController, and mailComposeController.
- The sendEmail function prepares the email using MFMailComposeViewController.
- The getRootViewController function allows us to present the mail app from our SwiftUI interface.
- The mailComposeController function captures the outcome from the mail application: sent, canceled, or failed.
import Foundation
import MessageUI
class MailHelper: NSObject, MFMailComposeViewControllerDelegate {
public static let shared = MailHelper()
private override init() { }
func sendEmail(subject: String, body: String, to: String){
guard MFMailComposeViewController.canSendMail() else {
print("Unable to send mail")
return
}
let mailComposeViewController = MFMailComposeViewController()
mailComposeViewController.mailComposeDelegate = self
mailComposeViewController.setToRecipients([to])
mailComposeViewController.setSubject(subject)
mailComposeViewController.setMessageBody(body, isHTML: false)
MailHelper.getRootViewController()?.present(mailComposeViewController, animated: true, completion: nil)
}
static func getRootViewController() -> UIViewController? {
guard let firstScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
return nil}
guard let firstWindow = firstScene.windows.first else {
return nil}
let viewController = firstWindow.rootViewController
return viewController}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?)
{
switch (result) {
case .sent:
print("Email sent successfully.")
break
case .cancelled:
print("Email sending canceled.")
break
case .failed:
print("Email sending failed.")
break
default:
break}
controller.dismiss(animated: true, completion: nil)
}
}
Creating the View for Sending Mail
Next, we will construct a simple SwiftUI view that allows users to input the Subject, To, and Body of the email. A button will trigger the sendEmail function in the MailHelper.
import SwiftUI
struct SendMailView: View {
@State var mailSubject: String = ""
@State var mailBody: String = ""
@State var mailTo: String = ""
var body: some View {
VStack(spacing: 20) {
TextField("Subject", text: $mailSubject)
TextField("Body", text: $mailBody)
TextField("Recipient", text: $mailTo)
Button {
MailHelper.shared.sendEmail(
subject: mailSubject,
body: mailBody,
to: mailTo
)
} label: {
Text("Send Email")}
}
.padding()
}
}
The Result:
Important Note: Avoid testing this functionality on a simulator; it requires a physical device. When you click the button, your device will launch the native mail application, pre-filling the Subject, To, and Body fields. If your device is not configured to send emails, it will display "Unable to send mail" in the console.
Adding Email Attachments in SwiftUI
We have successfully created an application that can compose and send emails via the native mail app. Now, let's enhance the functionality by allowing users to attach files, such as images.
We will modify our sendEmail function to support attachments and develop the SwiftUI interface to select an image for sending.
EmailAttachmentModel:
struct EmailAttachmentModel: Codable {
var data: Data
var mimeType: String
var fileName: String
}
Updated sendEmail Function:
func sendEmail(subject: String, body: String, to: String, attachment: EmailAttachmentModel?){
guard MFMailComposeViewController.canSendMail() else {
print("Unable to send mail")
return
}
let mailComposeViewController = MFMailComposeViewController()
mailComposeViewController.mailComposeDelegate = self
mailComposeViewController.setToRecipients([to])
mailComposeViewController.setSubject(subject)
mailComposeViewController.setMessageBody(body, isHTML: false)
if let attachment = attachment {
mailComposeViewController.addAttachmentData(attachment.data, mimeType: attachment.mimeType, fileName: attachment.fileName)}
MailHelper.getRootViewController()?.present(mailComposeViewController, animated: true, completion: nil)
}
Now, our MailHelper class can handle attachments, allowing users to enrich their emails.
Conclusion: Sending Emails with SwiftUI
In this guide, we've learned how to build a basic SwiftUI application that can create and send emails through the native mail app. We also developed a reusable MailHelper class and implemented error handling for cases when the email fails to send or the user cancels the process.
I hope this guide proves useful for your next application development project—happy coding!
Learn how to add email support in your SwiftUI project with this detailed video tutorial.
Discover how to send emails from SwiftUI, including handling attachments in this informative video.