はじめに
アプリ内からお問い合わせメールを送信できるアプリがあったので、どのように実装しているのか調査しました。
MFMailComposeViewController
というものを使用しているらしいのでSwiftUIでも使えるようにラップしました。
実装
MailView
import MessageUI
import SwiftUI
import UIKit
struct MailView: UIViewControllerRepresentable {
@Environment(\.presentationMode) var presentation
var address: [String]
var subject: String
var body: String
init(address: [String], subject: String, body: String) {
self.address = address
self.subject = subject
self.body = body
}
func makeCoordinator() -> Coordinator {
Coordinator(presentation: presentation)
}
func makeUIViewController(
context: UIViewControllerRepresentableContext<MailView>
) -> MFMailComposeViewController {
let viewController = MFMailComposeViewController()
viewController.mailComposeDelegate = context.coordinator
viewController.setToRecipients(address)
viewController.setSubject(subject)
viewController.setMessageBody(body, isHTML: false)
return viewController
}
func updateUIViewController(_: MFMailComposeViewController, context _: UIViewControllerRepresentableContext<MailView>) {}
}
extension MailView {
class Coordinator: NSObject {
@Binding var presentation: PresentationMode
init(
presentation: Binding<PresentationMode>
) {
_presentation = presentation
}
}
}
extension MailView.Coordinator: MFMailComposeViewControllerDelegate {
func mailComposeController(
_: MFMailComposeViewController,
didFinishWith _: MFMailComposeResult,
error _: Error?
) {
$presentation.wrappedValue.dismiss()
}
}
extension MailView {
static func canSendMail() -> Bool {
MFMailComposeViewController.canSendMail()
}
}
使い方
ContentView
import SwiftUI
struct ContentView: View {
@State var isShowMailView = false
var body: some View {
Button {
#if DEBUG
// シュミレータでは表示できない
#else
if MailView.canSendMail() {
isShowMailView = true
} else {
// MailViewを表示できない
}
#endif
} label: {
Text("メール")
}
.sheet(isPresented: $isShowMailView) {
MailView(
address: ["support@sample.com"],
subject: "サンプルアプリ",
body: "サンプルアプリです"
)
.edgesIgnoringSafeArea(.all)
}
}
}
注意
シュミレーターで表示しようとするとクラッシュします
必ずcanSendMail
でチェックを行ってください
if MailView.canSendMail() {
// MailViewを表示できる
} else {
// MailViewを表示できない
}
iPhone標準のメールアプリが使用できない状態だとクラッシュします
おわり
無事実装することができました。
公式ドキュメント