2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【SwiftUI】アプリ内でメール画面を表示する

Last updated at Posted at 2023-04-10

はじめに

アプリ内からお問い合わせメールを送信できるアプリがあったので、どのように実装しているのか調査しました。
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標準のメールアプリが使用できない状態だとクラッシュします

おわり

無事実装することができました。

公式ドキュメント

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?