Skip to content

Instantly share code, notes, and snippets.

@florentmorin
Last active April 13, 2024 17:15
Show Gist options
  • Save florentmorin/4be7ca70c973c29cbeebbed4e2ef20ba to your computer and use it in GitHub Desktop.
Save florentmorin/4be7ca70c973c29cbeebbed4e2ef20ba to your computer and use it in GitHub Desktop.
A small hack to make `MFMailComposeViewController` and `MFMessageComposeViewController` working fine with SwiftUI
//
// ContentView.swift
// MailDemo
//
// Created by Florent Morin on 29/06/2019.
// Copyright © 2019 Morin Innovation. All rights reserved.
//
// Medium link: https://medium.com/@florentmorin/messageui-swiftui-and-uikit-integration-82d91159b0bd
// Sample source code: https://github.com/florentmorin/SwiftUIAndMessageUI
import SwiftUI
import MessageUI
/// Main View
struct ContentView: View {
/// The delegate required by `MFMailComposeViewController`
private let mailComposeDelegate = MailDelegate()
/// The delegate required by `MFMessageComposeViewController`
private let messageComposeDelegate = MessageDelegate()
var body: some View {
VStack {
Spacer()
Button(action: {
self.presentMailCompose()
}) {
Text("Send email")
}
Spacer()
Button(action: {
self.presentMessageCompose()
}) {
Text("Send message")
}
Spacer()
}
}
}
// MARK: The mail part
extension ContentView {
/// Delegate for view controller as `MFMailComposeViewControllerDelegate`
private class MailDelegate: NSObject, MFMailComposeViewControllerDelegate {
func mailComposeController(_ controller: MFMailComposeViewController,
didFinishWith result: MFMailComposeResult,
error: Error?) {
<# Customize here #>
controller.dismiss(animated: true)
}
}
/// Present an mail compose view controller modally in UIKit environment
private func presentMailCompose() {
guard MFMailComposeViewController.canSendMail() else {
return
}
let vc = UIApplication.shared.keyWindow?.rootViewController
let composeVC = MFMailComposeViewController()
composeVC.mailComposeDelegate = mailComposeDelegate
<# Customize here #>
vc?.present(composeVC, animated: true)
}
}
// MARK: The message part
extension ContentView {
/// Delegate for view controller as `MFMessageComposeViewControllerDelegate`
private class MessageDelegate: NSObject, MFMessageComposeViewControllerDelegate {
func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
// Customize here
controller.dismiss(animated: true)
}
}
/// Present an message compose view controller modally in UIKit environment
private func presentMessageCompose() {
guard MFMessageComposeViewController.canSendText() else {
return
}
let vc = UIApplication.shared.keyWindow?.rootViewController
let composeVC = MFMessageComposeViewController()
composeVC.messageComposeDelegate = messageComposeDelegate
<# Customize here #>
vc?.present(composeVC, animated: true)
}
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
@legolasW
Copy link

Hello there, thanks for the solution. Unfortunately it does not work on iPad. May I ask if you know why? Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment