Skip to content

Instantly share code, notes, and snippets.

@EnesKaraosman
Created December 10, 2020 05:48
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save EnesKaraosman/5cb43dca8317b864c754b4b44753ac63 to your computer and use it in GitHub Desktop.
Save EnesKaraosman/5cb43dca8317b864c754b4b44753ac63 to your computer and use it in GitHub Desktop.
Mail composer in SwiftUI
// https://stackoverflow.com/questions/56784722/swiftui-send-email
public struct MailView: UIViewControllerRepresentable {
@Environment(\.presentationMode) var presentation
@Binding var result: Result<MFMailComposeResult, Error>?
public var configure: ((MFMailComposeViewController) -> Void)?
public class Coordinator: NSObject, MFMailComposeViewControllerDelegate {
@Binding var presentation: PresentationMode
@Binding var result: Result<MFMailComposeResult, Error>?
init(presentation: Binding<PresentationMode>,
result: Binding<Result<MFMailComposeResult, Error>?>) {
_presentation = presentation
_result = result
}
public func mailComposeController(_ controller: MFMailComposeViewController,
didFinishWith result: MFMailComposeResult,
error: Error?) {
defer {
$presentation.wrappedValue.dismiss()
}
guard error == nil else {
self.result = .failure(error!)
return
}
self.result = .success(result)
}
}
public func makeCoordinator() -> Coordinator {
return Coordinator(presentation: presentation,
result: $result)
}
public func makeUIViewController(context: UIViewControllerRepresentableContext<MailView>) -> MFMailComposeViewController {
let vc = MFMailComposeViewController()
vc.mailComposeDelegate = context.coordinator
configure?(vc)
return vc
}
public func updateUIViewController(
_ uiViewController: MFMailComposeViewController,
context: UIViewControllerRepresentableContext<MailView>) {
}
}
@EnesKaraosman
Copy link
Author

EnesKaraosman commented Dec 10, 2020

Usage;

    @State private var result: Result<MFMailComposeResult, Error>? = nil
    @State private var isShowingMailView = false
    
    var body: some View {
        Form {
            Button(action: {
                if MFMailComposeViewController.canSendMail() {
                    self.isShowingMailView.toggle()
                } else {
                    print("Can't send emails from this device")
                }
                if result != nil {
                    print("Result: \(String(describing: result))")
                }
            }) {
                HStack {
                    Image(systemName: "envelope")
                    Text("Contact Us")
                }
            }
            // .disabled(!MFMailComposeViewController.canSendMail())
        }
        .sheet(isPresented: $isShowingMailView) {
            MailView(result: $result) { composer in
                composer.setSubject("Secret")
                composer.setToRecipients(["eneskaraosman53@gmail.com"])
            }
        }
    }

@jangelsb
Copy link

jangelsb commented May 28, 2022

The only issue is that the details of the email (subject, recipients, etc) get set after the view is presented. Any idea on how to fix that?

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