🪶

SwiftUIでMailViewを使用する

2024/11/28に公開

お問い合わせフォームを作らずに送信

WebViewでお問い合わせフォームを作成するか、アプリ内に独自のものを作ることがあるが、Swiftには標準機能でメール送信ができる機能がある。

それがMailView

こちらを参考に作成

注意点としては実機でないと試せなかったです。シュミレーターでもAppleのアカウントにログインしてたらできるかも?

https://medium.com/@williewilson99/show-mail-view-in-swiftui-28bc5112d225
https://qiita.com/SNQ-2001/items/21b351486ccfcf468f0f

ざっくりとですがデモアプリ作ってみましたご興味ある方はお試しください。

example

import SwiftUI
import WebKit
import MessageUI

struct SettingsView: View {
    @State private var showTerms = false
    @State private var showPrivacy = false
    @State private var isShowingMailView = false
    
    var body: some View {
        VStack {
            List {
                Button("利用規約") {
                    showTerms = true
                }
                Button("プライバシーポリシー") {
                    showPrivacy = true
                }
                // メール送信ボタン
                Button("お問い合わせ") {
                    if MFMailComposeViewController.canSendMail() {
                        isShowingMailView = true
                    } else {
                        // メールアドレスをエンコード
                        let email = "hogehoge@gmail.com"
                        let subject = "お問い合わせ"
                        let encodedSubject = subject.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
                        
                        let urlString = "mailto:\(email)?subject=\(encodedSubject)"
                        
                        if let emailURL = URL(string: urlString) {
                            DispatchQueue.main.async {
                                UIApplication.shared.open(emailURL) { success in
                                    if !success {
                                        // エラーハンドリング
                                        print("メールアプリを開けませんでした")
                                    }
                                }
                            }
                        }
                    }
                }
            }
            .sheet(isPresented: $isShowingMailView) {
                MailView(isShowing: $isShowingMailView)
            }
        }
        .navigationTitle("設定")
        .navigationBarTitleDisplayMode(.inline)
        .sheet(isPresented: $showTerms) {
            WebViewContainer(urlString: "https://github.co.jp/")
        }
        .sheet(isPresented: $showPrivacy) {
            WebViewContainer(urlString: "https://github.co.jp/")
        }
        
        GroupBox("設定") {
            VStack {
                Text("ffffff")
            }
        }
    }
}

#Preview {
    SettingsView()
}

struct WebViewContainer: View {
    let urlString: String
    
    var body: some View {
        WebView(urlString: urlString)
            .edgesIgnoringSafeArea(.bottom)
    }
}

struct WebView: UIViewRepresentable {
    let urlString: String
    
    func makeUIView(context: Context) -> WKWebView {
        return WKWebView()
    }
    
    func updateUIView(_ webView: WKWebView, context: Context) {
        if let url = URL(string: urlString) {
            let request = URLRequest(url: url)
            webView.load(request)
        }
    }
}

// Mail
struct MailView: UIViewControllerRepresentable {
    @Binding var isShowing: Bool
    
    func makeUIViewController(context: Context) -> MFMailComposeViewController {
        let vc = MFMailComposeViewController()
        vc.mailComposeDelegate = context.coordinator
        
        // メールの初期設定
        vc.setToRecipients(["hogehoge@gmail.com"])
        vc.setSubject("お問い合わせ")
        vc.setMessageBody("", isHTML: false)
        
        return vc
    }
    
    func updateUIViewController(_ uiViewController: MFMailComposeViewController, context: Context) {}
    
    func makeCoordinator() -> Coordinator {
        Coordinator(isShowing: $isShowing)
    }
    
    class Coordinator: NSObject, MFMailComposeViewControllerDelegate {
        @Binding var isShowing: Bool
        
        init(isShowing: Binding<Bool>) {
            _isShowing = isShowing
        }
        
        func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
            isShowing = false
        }
    }
}

Discussion