【iOS】跳转邮箱发送邮件,支持系统内多个邮箱的方案 swift 实现

2021-09-24 11:10:25 浏览数 (3)

我们永远无法知道运行应用程序的iPhone / iPad是否安装了Apple的Mail应用程序,因为用户可以删除它。

一、前言

  • 网上一般都让这么写
代码语言:javascript复制
let email = "foo@bar.com"
if let url = URL(string: "mailto:(email)") {
   UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
  • 但是最好支持多个电子邮件客户端。下面的代码以更优雅的方式处理电子邮件发送。代码流为:
    1. 如果已安装Mail应用程序,请打开Mail的编辑器,并预先填充提供的数据
    2. 否则,请尝试依次打开Gmail应用,Outlook,Yahoo邮件和Spark。
    3. 如果未安装这些客户端,则回退为默认值mailto:…,提示用户安装Apple的Mail应用程序。

二、方案(代码,大家 cv 时求个赞)

  • 代码是用Swift 5编写的:
代码语言:javascript复制
    import MessageUI
    import UIKit

    class SendEmailViewController: UIViewController, MFMailComposeViewControllerDelegate {

        @IBAction func sendEmail(_ sender: UIButton) {
            // Modify following variables with your text / recipient
            let recipientEmail = "test@email.com"
            let subject = "Multi client email support"
            let body = "This code supports sending email via multiple different email apps on iOS! :)"

            // Show default mail composer
            if MFMailComposeViewController.canSendMail() {
                let mail = MFMailComposeViewController()
                mail.mailComposeDelegate = self
                mail.setToRecipients([recipientEmail])
                mail.setSubject(subject)
                mail.setMessageBody(body, isHTML: false)

                present(mail, animated: true)

            // Show third party email composer if default Mail app is not present
            } else if let emailUrl = createEmailUrl(to: recipientEmail, subject: subject, body: body) {
                UIApplication.shared.open(emailUrl)
            }
        }

        private func createEmailUrl(to: String, subject: String, body: String) -> URL? {
            let subjectEncoded = subject.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
            let bodyEncoded = body.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!

            let gmailUrl = URL(string: "googlegmail://co?to=(to)&subject=(subjectEncoded)&body=(bodyEncoded)")
            let outlookUrl = URL(string: "ms-outlook://compose?to=(to)&subject=(subjectEncoded)")
            let yahooMail = URL(string: "ymail://mail/compose?to=(to)&subject=(subjectEncoded)&body=(bodyEncoded)")
            let sparkUrl = URL(string: "readdle-spark://compose?recipient=(to)&subject=(subjectEncoded)&body=(bodyEncoded)")
            let defaultUrl = URL(string: "mailto:(to)?subject=(subjectEncoded)&body=(bodyEncoded)")

            if let gmailUrl = gmailUrl, UIApplication.shared.canOpenURL(gmailUrl) {
                return gmailUrl
            } else if let outlookUrl = outlookUrl, UIApplication.shared.canOpenURL(outlookUrl) {
                return outlookUrl
            } else if let yahooMail = yahooMail, UIApplication.shared.canOpenURL(yahooMail) {
                return yahooMail
            } else if let sparkUrl = sparkUrl, UIApplication.shared.canOpenURL(sparkUrl) {
                return sparkUrl
            }

            return defaultUrl
        }

        func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
            controller.dismiss(animated: true)
        }
    }
  • 请注意,我故意错过了Outlook应用的正文,因为它无法解析它。
  • 您还必须向Info.plist文件添加以下代码,该文件将使用的UR1查询方案列入白名单。
代码语言:javascript复制
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>googlegmail</string>
    <string>ms-outlook</string>
    <string>readdle-spark</string>
    <string>ymail</string>
</array>

三、结语

  • 如果回答对你有帮助求个赞呗 ~

1 人点赞