Skip to main content

Composing Mail in SwiftUI

//
// MailView.swift
// sky-earth-human
//
// Source: https://stackoverflow.com/a/58693164/9568307
//

import MessageUI
import SwiftUI
import UIKit

struct MailView: UIViewControllerRepresentable {
@Environment(\.presentationMode) var presentation
@Binding var result: Result<MFMailComposeResult, Error>?

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
}

func mailComposeController(_: MFMailComposeViewController,
didFinishWith result: MFMailComposeResult,
error: Error?)
{
defer {
$presentation.wrappedValue.dismiss()
}
guard error == nil else {
self.result = .failure(error!)
return
}
self.result = .success(result)
}
}

func makeCoordinator() -> Coordinator {
return Coordinator(presentation: presentation,
result: $result)
}

func makeUIViewController(context: UIViewControllerRepresentableContext<MailView>) -> MFMailComposeViewController {
let vc = MFMailComposeViewController()
vc.setToRecipients(["[email protected]"])
vc.setSubject("ํ•˜๋Š˜๋•…์‚ฌ๋žŒ ๊ด€๋ จ ๋ฌธ์˜")
vc.setMessageBody("""

๋ฌธ์˜ ๋‚ด์šฉ์„ ์—ฌ๊ธฐ์— ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.

--------------------

ํ•˜๋Š˜๋•…์‚ฌ๋žŒ ๋ฒ„์ „: ((Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String)!)
iOS ๋ฒ„์ „: (UIDevice.current.systemVersion)
๊ธฐ๊ธฐ: (UIDevice.current.model)

""", isHTML: false)
vc.mailComposeDelegate = context.coordinator
return vc
}

func updateUIViewController(_: MFMailComposeViewController,
context _: UIViewControllerRepresentableContext<MailView>) {}
}
Button(action: {self.isShowingMailView.toggle()}) {
Image(systemName: "paperplane.fill").frame(alignment: .center)
Text("๋ฒ„๊ทธ ์ œ๋ณด ๋ฐ ๊ธฐ๋Šฅ ์ œ์•ˆํ•˜๊ธฐ")
}
.disabled(!MFMailComposeViewController.canSendMail())
.sheet(isPresented: $isShowingMailView) {
MailView(result: self.$result)
}