DEV Community

Trần Thanh Vũ
Trần Thanh Vũ

Posted on • Edited on

2

How to send emails in swiftUI

Opening an email in an iOS application is a common feature, and I think most applications have it. But sometimes developers' complex mind makes its implementation more complex than it is.

In the case of swiftUI, the implementation doesn't change, you can use the old code to implement it. In my project, it works perfectly. You can find the full version of the code below.

Here are some requirements implemented in that file.

  1. Create and use an object to help you checking the status of the mail service and handling the MailCompose's delegate.

    I used a static object to able to reuse it in my project.

    
        class EmailHelper: NSObject {
            /// singleton
            static let shared = EmailHelper()
            private override init() {}
        }
    
    


  2. Able to open the external mail or settings app in case users didn't set up any email.

    I just supported the external mails app such as Gmail, Mail. So, if you want to add more, please do it yourself. Note, you have to add Schemes of the app which you want to support.

    
        /// Remember to add the below code to Info.plist
        ///    <key>LSApplicationQueriesSchemes</key>
        ///    <array>
        ///       <string>googlegmail</string>
        ///    </array>
    
    


  3. Related to swiftUI, you don't have to use UIViewRepresentable or UIViewControllerRepresentable here, because you just want to open the mail but don't want to embed it in a View

    
        struct SettingsView: View {
            var body: some View {
                return Form {
                    Section(header: Text("SUPPORT")) {
                        Button("Help") {
                            EmailHelper.shared.send(subject: "Help", body: "", to: [GlobalConstant.App.contactEmail])
                        }
                    }
                }
            }
        }
    


Happy coding!


//
// EmailHelper.swift
// CarLicenceExam
//
// Created by Yoyo on 2/7/21.
//
import SwiftUI
import MessageUI
class EmailHelper: NSObject {
/// singleton
static let shared = EmailHelper()
private override init() {}
}
extension EmailHelper {
/// Remember to add the below code to Info.plist
/// <key>LSApplicationQueriesSchemes</key>
/// <array>
/// <string>googlegmail</string>
/// </array>
func send(subject: String, body: String, to: [String]) {
guard let viewController = UIApplication.shared.windows.first?.rootViewController else {
return
}
if !MFMailComposeViewController.canSendMail() {
let subjectEncoded = subject.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
let bodyEncoded = body.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
let mails = to.joined(separator: ",")
let alert = UIAlertController(title: "Cannot open Mail!", message: "", preferredStyle: .actionSheet)
var haveExternalMailbox = false
if let defaultUrl = URL(string: "mailto:\(mails)?subject=\(subjectEncoded)&body=\(bodyEncoded)"),
UIApplication.shared.canOpenURL(defaultUrl) {
haveExternalMailbox = true
alert.addAction(UIAlertAction(title: "Mail", style: .default, handler: { (action) in
UIApplication.shared.open(defaultUrl)
}))
}
if let gmailUrl = URL(string: "googlegmail://co?to=\(mails)&subject=\(subjectEncoded)&body=\(bodyEncoded)"),
UIApplication.shared.canOpenURL(gmailUrl) {
haveExternalMailbox = true
alert.addAction(UIAlertAction(title: "Gmail", style: .default, handler: { (action) in
UIApplication.shared.open(gmailUrl)
}))
}
if haveExternalMailbox {
alert.message = "Would you like to open an external mailbox?"
} else {
alert.message = "Please add your mail to Settings before using the mail service."
if let settingsUrl = URL(string: UIApplication.openSettingsURLString),
UIApplication.shared.canOpenURL(settingsUrl) {
alert.addAction(UIAlertAction(title: "Open Settings App", style: .default, handler: { (action) in
UIApplication.shared.open(settingsUrl)
}))
}
}
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
viewController.present(alert, animated: true, completion: nil)
return
}
let mailCompose = MFMailComposeViewController()
mailCompose.setSubject(subject)
mailCompose.setMessageBody(body, isHTML: false)
mailCompose.setToRecipients(to)
mailCompose.mailComposeDelegate = self
viewController.present(mailCompose, animated: true, completion: nil)
}
}
// MARK: - MFMailComposeViewControllerDelegate
extension EmailHelper: MFMailComposeViewControllerDelegate {
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
controller.dismiss(animated: true, completion: nil)
}
}

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay