How to open mail app from Swift

前端 未结 15 1271
被撕碎了的回忆
被撕碎了的回忆 2020-11-30 20:18

Im working on a simple swift app where the user inputs an email address and presses a button which opens the mail app, with the entered address in the address bar. I know ho

相关标签:
15条回答
  • 2020-11-30 20:34

    For Swift 4.2 and above

    let supportEmail = "abc@xyz.com"
    if let emailURL = URL(string: "mailto:\(supportEmail)"), UIApplication.shared.canOpenURL(emailURL)
    {
        UIApplication.shared.open(emailURL, options: [:], completionHandler: nil)
    }
    

    Give the user to choose many mail options(like iCloud, google, yahoo, Outlook.com - if no mail is pre-configured in his phone) to send email.

    0 讨论(0)
  • 2020-11-30 20:35

    Updated answer from Stephen Groom for Swift 3

    let email = "email@email.com"
    let url = URL(string: "mailto:\(email)")
    UIApplication.shared.openURL(url!)
    
    0 讨论(0)
  • 2020-11-30 20:36

    For those of us still lagging behind on Swift 2.3 here is Gordon's answer in our syntax:

    let email = "foo@bar.com"
    if let url = NSURL(string: "mailto:\(email)") {
       UIApplication.sharedApplication().openURL(url)
    }
    
    0 讨论(0)
  • 2020-11-30 20:38

    You can use simple mailto: links in iOS to open the mail app.

    let email = "foo@bar.com"
    if let url = URL(string: "mailto:\(email)") {
      if #available(iOS 10.0, *) {
        UIApplication.shared.open(url)
      } else {
        UIApplication.shared.openURL(url)
      }    
    }
    
    0 讨论(0)
  • 2020-11-30 20:38

    This is a straight forward solution of 3 steps in Swift.

    import MessageUI
    

    Add to conform the Delegate

    MFMailComposeViewControllerDelegate
    

    And just create your method:

        func sendEmail() {
        if MFMailComposeViewController.canSendMail() {
            let mail = MFMailComposeViewController()
            mail.mailComposeDelegate = self
            mail.setToRecipients(["support@mail.com"])
            mail.setSubject("Support App")
            mail.setMessageBody("<p>Send us your issue!</p>", isHTML: true)
            presentViewController(mail, animated: true, completion: nil)
        } else {
            // show failure alert
        }
    }
    
    func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?) {
        controller.dismissViewControllerAnimated(true, completion: nil)
    }
    
    0 讨论(0)
  • 2020-11-30 20:39

    While other answers are all correct, you can never know if the iPhone/iPad that is running your application has the Apple's Mail app installed or not as it can be deleted by the user.

    It is better to support multiple email clients. Following code handles the email sending in a more graceful way. The flow of the code is:

    • If Mail app is installed, open Mail's composer pre-filled with provided data
    • Otherwise, try opening the Gmail app, then Outlook, then Yahoo mail, then Spark, in this order
    • If none of those clients are installed, fallback to default mailto:.. that prompts the user to install Apple's Mail app.

    Code is written in Swift 5:

        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: .urlQueryAllowed)!
                let bodyEncoded = body.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
                
                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)
            }
        }
    

    Please note that I intentionally missed out the body for the Outlook app, as it is not able to parse it.

    You also have to add following code to Info.plist file that whitelists the URl query schemes that are used.

    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>googlegmail</string>
        <string>ms-outlook</string>
        <string>readdle-spark</string>
        <string>ymail</string>
    </array>
    
    0 讨论(0)
提交回复
热议问题