SwiftUI: Отправить письмо - PullRequest
1 голос
/ 27 июня 2019

В обычном UIViewController в Swift я использую этот код для отправки почты.

let mailComposeViewController = configuredMailComposeViewController()

mailComposeViewController.navigationItem.leftBarButtonItem?.style = .plain
mailComposeViewController.navigationItem.rightBarButtonItem?.style = .plain
mailComposeViewController.navigationBar.tintColor = UIColor.white

if MFMailComposeViewController.canSendMail() {
    self.present(mailComposeViewController, animated: true, completion: nil)
} else {
    self.showSendMailErrorAlert()
}

Как мне добиться того же в SwiftUI?

Нужно ли использовать UIViewControllerRepresentable?

Ответы [ 2 ]

1 голос
/ 27 июня 2019

Как вы упомянули, вам нужно перенести компонент на SwiftUI через UIViewControllerRepresentable.

Вот простая реализация:

struct MailView: UIViewControllerRepresentable {

    @Binding var isShowing: Bool
    @Binding var result: Result<MFMailComposeResult, Error>?

    class Coordinator: NSObject, MFMailComposeViewControllerDelegate {

        @Binding var isShowing: Bool
        @Binding var result: Result<MFMailComposeResult, Error>?

        init(isShowing: Binding<Bool>,
             result: Binding<Result<MFMailComposeResult, Error>?>) {
            $isShowing = isShowing
            $result = result
        }

        func mailComposeController(_ controller: MFMailComposeViewController,
                                   didFinishWith result: MFMailComposeResult,
                                   error: Error?) {
            defer {
                isShowing = false
            }
            guard error == nil else {
                self.result = .failure(error!)
                return
            }
            self.result = .success(result)
        }
    }

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

    func makeUIViewController(context: UIViewControllerRepresentableContext<MailView>) -> MFMailComposeViewController {
        let vc = MFMailComposeViewController()
        vc.mailComposeDelegate = context.coordinator
        return vc
    }

    func updateUIViewController(_ uiViewController: MFMailComposeViewController,
                                context: UIViewControllerRepresentableContext<MailView>) {

    }
}

Использование :

struct ContentView: View {

    @State var result: Result<MFMailComposeResult, Error>?
    @State var isShowingMailView = false

    var body: some View {
        ZStack {
            VStack {
                Button(action: {
                    self.isShowingMailView.toggle()
                }) {
                    Text("Show mail view")
                }
                if result != nil {
                    Text("Result: \(String(describing: result))")
                    .lineLimit(nil)
                }
            }
            if (isShowingMailView) {
                mailView()
                .transition(.move(edge: .bottom))
                .animation(.basic())
            }
        }


    }

    private func mailView() -> some View {
        MFMailComposeViewController.canSendMail() ?
            AnyView(MailView(isShowing: $isShowingMailView, result: $result)) :
            AnyView(Text("Can't send emails from this device"))
    }
}

Примечания :

Я использую ZStack, чтобы показать это, так как поведение Modal было весьма противоречивым.

(протестировано на iPhone 7 Plus под управлением iOS 13 - работает как шарм)

0 голосов
/ 30 июня 2019

Я только что написал небольшую статью об этом. Это альтернативный ответ, работа с UIKit для электронной почты вместо SwiftUI.

https://link.medium.com/posgdRBMWX

...