Composing Emails in SwiftUI Using A View Modifier

Gabriel Theodoropoulos
11 min readJun 17, 2021
Code snippet screenshot highlighting the topic of the article, containing the implementation of a Button in SwiftUI with title “Send Email” and of a custom view modifier called email composer that demonstrates the final result of this post.

Just a couple of weeks ago, I had discussed in this previous post about the MFMailComposeViewController; a class that allows to present and use a system provided view controller in order to compose and send emails through our own applications. The discussion on that post was around a UIKit based application explaining how that class works.

In this post today, I’m going to talk about how to integrate MFMailComposeViewController in SwiftUI projects, since there is no native SwiftUI alternative. But that’s going to be just the half of the content; the other half is a step by step guidance how to hide everything behind a custom view modifier, turning that way email composing into a deeply SwiftUI-looking like and straightforward task.

To get a taste, this is what we are going to end up with:

Button("Send Email") {
showEmailComposer = true
}
.emailComposer(isPresented: $showEmailComposer,
emailData: emailData) { result in
// Handle send results.
}

Note that I will not focus on the details of MFMailComposeViewController in this post. I’ve covered that in the first post, so all I’ll do here is to demonstrate how to integrate it in SwiftUI.

The EmailData type

When presenting an MFMailComposeViewController instance, we can optionally provide default content to it. That content may include the subject, one or more recipients, email’s body, attachments, and a few more.

In order to handle all that easily, we’re going to start off by creating a custom type that will be holding any of the data that we can possibly set before presenting the email composer. It’s a simple struct with a few properties and an inner custom type to represent attachment data:

struct EmailData {
var subject: String = ""
var recipients: [String]?
var body: String = ""
var isBodyHTML = false
var attachments = [AttachmentData]()

struct AttachmentData {
var data: Data
var mimeType: String
var fileName: String
}
}

Note that the data type of each property is in accordance to the data type of the respective property in the MFMailComposeViewController class. EmailData is going to be quite handy…

--

--

Gabriel Theodoropoulos

An iOS & macOS app maker writing code in Swift. Author of countless programming tutorials. Content creator. https://serialcoder.dev