我工作在一个简单的快速应用程序,其中用户输入一个电子邮件地址,并按下一个按钮,打开邮件应用程序,与输入的地址在地址栏。我知道在 Objective-C 怎么做但是在斯威夫特就不行了。
我不知道你是想切换到邮件应用程序本身或只是打开和发送电子邮件。对于链接到按钮 IBAction 的后一个选项:
import UIKit import MessageUI class ViewController: UIViewController, MFMailComposeViewControllerDelegate { @IBAction func launchEmail(sender: AnyObject) { var emailTitle = "Feedback" var messageBody = "Feature request or bug report?" var toRecipents = ["friend@stackoverflow.com"] var mc: MFMailComposeViewController = MFMailComposeViewController() mc.mailComposeDelegate = self mc.setSubject(emailTitle) mc.setMessageBody(messageBody, isHTML: false) mc.setToRecipients(toRecipents) self.presentViewController(mc, animated: true, completion: nil) } func mailComposeController(controller:MFMailComposeViewController, didFinishWithResult result:MFMailComposeResult, error:NSError) { switch result { case MFMailComposeResultCancelled: print("Mail cancelled") case MFMailComposeResultSaved: print("Mail saved") case MFMailComposeResultSent: print("Mail sent") case MFMailComposeResultFailed: print("Mail sent failure: \(error?.localizedDescription)") default: break } self.dismissViewControllerAnimated(true, completion: nil) } }
您可以使用简单的 mailto: 链接在 iOS 中打开邮件应用程序。
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) } }
Swift 2,带 可用性检查:
import MessageUI if MFMailComposeViewController.canSendMail() { let mail = MFMailComposeViewController() mail.mailComposeDelegate = self mail.setToRecipients(["test@test.test"]) mail.setSubject("Bla") mail.setMessageBody("<b>Blabla</b>", isHTML: true) presentViewController(mail, animated: true, completion: nil) } else { print("Cannot send mail") // give feedback to the user } // MARK: - MFMailComposeViewControllerDelegate func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?) { switch result.rawValue { case MFMailComposeResultCancelled.rawValue: print("Cancelled") case MFMailComposeResultSaved.rawValue: print("Saved") case MFMailComposeResultSent.rawValue: print("Sent") case MFMailComposeResultFailed.rawValue: print("Error: \(error?.localizedDescription)") default: break } controller.dismissViewControllerAnimated(true, completion: nil) }
这是一个直接的解决方案的3个步骤在迅捷。
import MessageUI
添加以符合委托
MFMailComposeViewControllerDelegate
然后创建你的方法:
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) }
斯蒂芬 · 格鲁姆为斯威夫特3更新的答案
let email = "email@email.com" let url = URL(string: "mailto:\(email)") UIApplication.shared.openURL(url!)
在 Swift 3中,确保添加 import MessageUI并且需要遵守 MFMailComposeViewControllerDelegate协议。
func sendEmail() { if MFMailComposeViewController.canSendMail() { let mail = MFMailComposeViewController() mail.mailComposeDelegate = self mail.setToRecipients(["ved.ios@yopmail.com"]) mail.setMessageBody("<p>You're so awesome!</p>", isHTML: true) present(mail, animated: true) } else { // show failure alert } }
议定书:
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) { controller.dismiss(animated: true) }
对于那些仍然落后于 Swift 2.3的人,以下是 Gordon 在我们的语法中给出的答案:
let email = "foo@bar.com" if let url = NSURL(string: "mailto:\(email)") { UIApplication.sharedApplication().openURL(url) }
@IBAction func launchEmail(sender: AnyObject) { if if MFMailComposeViewController.canSendMail() { var emailTitle = "Feedback" var messageBody = "Feature request or bug report?" var toRecipents = ["friend@stackoverflow.com"] var mc: MFMailComposeViewController = MFMailComposeViewController() mc.mailComposeDelegate = self mc.setSubject(emailTitle) mc.setMessageBody(messageBody, isHTML: false) mc.setToRecipients(toRecipents) self.present(mc, animated: true, completion: nil) } else { // show failure alert } } func mailComposeController(controller:MFMailComposeViewController, didFinishWithResult result:MFMailComposeResult, error:NSError) { switch result { case .cancelled: print("Mail cancelled") case .saved: print("Mail saved") case .sent: print("Mail sent") case .failed: print("Mail sent failure: \(error?.localizedDescription)") default: break } self.dismiss(animated: true, completion: nil) }
请注意,并非所有用户都将其设备配置为发送电子邮件,这就是为什么我们需要在尝试发送之前检查 canSendMail ()的结果。还需要注意的是,您需要捕获 did FinishWith 回调以便解除邮件窗口。
以下是 Swift 4的外观:
import MessageUI if MFMailComposeViewController.canSendMail() { let mail = MFMailComposeViewController() mail.mailComposeDelegate = self mail.setToRecipients(["test@test.test"]) mail.setSubject("Bla") mail.setMessageBody("<b>Blabla</b>", isHTML: true) present(mail, animated: true, completion: nil) } else { print("Cannot send mail") // give feedback to the user } func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) { switch result.rawValue { case MFMailComposeResult.cancelled.rawValue: print("Cancelled") case MFMailComposeResult.saved.rawValue: print("Saved") case MFMailComposeResult.sent.rawValue: print("Sent") case MFMailComposeResult.failed.rawValue: print("Error: \(String(describing: error?.localizedDescription))") default: break } controller.dismiss(animated: true, completion: nil) }
如果你只是想通过 URL打开邮件客户端,这里有一个 Swift 4的更新:
URL
let email = "foo@bar.com" if let url = URL(string: "mailto:\(email)") { UIApplication.shared.open(url, options: [:], completionHandler: nil) }
这对我来说完全没问题:)
适用于 Swift 4.2 + 和 iOS 9 +
let appURL = URL(string: "mailto:test@example.com")! if #available(iOS 10.0, *) { UIApplication.shared.open(appURL, options: [:], completionHandler: nil) } else { UIApplication.shared.openURL(appURL) }
将 test@example.com 替换为您想要的电子邮件地址。
还可以在 To、 Cc 和 Bcc 字段中包含 主题字段、 信息和 多个收件人:
mailto:foo@example.com?cc=bar@example.com&subject=Greetings%20from%20Cupertino!&body=Wish%20you%20were%20here!
您应该尝试使用内置邮件编写器发送邮件,如果失败,请尝试使用 share:
func contactUs() { let email = "info@example.com" // insert your email here let subject = "your subject goes here" let bodyText = "your body text goes here" // https://developer.apple.com/documentation/messageui/mfmailcomposeviewcontroller if MFMailComposeViewController.canSendMail() { let mailComposerVC = MFMailComposeViewController() mailComposerVC.mailComposeDelegate = self as? MFMailComposeViewControllerDelegate mailComposerVC.setToRecipients([email]) mailComposerVC.setSubject(subject) mailComposerVC.setMessageBody(bodyText, isHTML: false) self.present(mailComposerVC, animated: true, completion: nil) } else { print("Device not configured to send emails, trying with share ...") let coded = "mailto:\(email)?subject=\(subject)&body=\(bodyText)".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) if let emailURL = URL(string: coded!) { if #available(iOS 10.0, *) { if UIApplication.shared.canOpenURL(emailURL) { UIApplication.shared.open(emailURL, options: [:], completionHandler: { (result) in if !result { print("Unable to send email.") } }) } } else { UIApplication.shared.openURL(emailURL as URL) } } } }
而其他答案都是正确的,你永远不会知道运行你的应用程序的 iPhone/iPad 是否安装了苹果的邮件应用程序或不,因为它可以被用户删除。
最好支持多个电子邮件客户端。以下代码以更优雅的方式处理电子邮件发送。代码的流程是:
mailto:..
代码是用 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)&body=\(bodyEncoded)") 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) } }
您还必须向 Info.plist文件添加以下代码,以列出所使用的 URL 查询方案。
Info.plist
<key>LSApplicationQueriesSchemes</key> <array> <string>googlegmail</string> <string>ms-outlook</string> <string>readdle-spark</string> <string>ymail</string> </array>
适用于 Swift 4.2及以上版本
let supportEmail = "abc@xyz.com" if let emailURL = URL(string: "mailto:\(supportEmail)"), UIApplication.shared.canOpenURL(emailURL) { UIApplication.shared.open(emailURL, options: [:], completionHandler: nil) }
让用户选择许多邮件选项(如 iCloud、谷歌、雅虎、 Outlook.com ——如果手机中没有预先配置邮件的话)来发送电子邮件。
在视图控制器中,您希望从哪里打开您的邮件应用程序的水龙头。
将此函数放入控制器中。
func showMailComposer(){ guard MFMailComposeViewController.canSendMail() else { return } let composer = MFMailComposeViewController() composer.mailComposeDelegate = self composer.setToRecipients(["abc@gmail.com"]) // email id of the recipient composer.setSubject("testing!!!") composer.setMessageBody("this is a test mail.", isHTML: false) present(composer, animated: true, completion: nil) }
Extend your View Controller and conform to the MFMailComposeViewControllerDelegate.
Put this method and handle the failure, sending of your mails.
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) { if let _ = error { controller.dismiss(animated: true, completion: nil) return } controller.dismiss(animated: true, completion: nil) }
在我的情况下,我只是试图打开邮件应用程序,而没有创建一个电子邮件草稿。
如果有人碰巧发现了这个问题,并且实际上正在尝试做同样的事情,这里我使用的代码是:
private var openMailAppButton: some View { Button { if let emailUrl = mailAppUrl() { UIApplication.shared.open(emailUrl) } } label: { Text("OPEN MAIL APP") } } private func mailAppUrl() -> URL? { let gmailUrl = URL(string: "googlegmail://") let outlookUrl = URL(string: "ms-outlook://") let yahooMail = URL(string: "ymail://") let sparkUrl = URL(string: "readdle-spark://") let defaultUrl = URL(string: "message://") if let defaultUrl = defaultUrl, UIApplication.shared.canOpenURL(defaultUrl) { return defaultUrl } else 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 }
我创建了一个 Swift 软件包来处理这个问题,并且还实现了一个检查,如果他们有多个电子邮件客户端。
Https://github.com/joe-scotto/emaillink
Func mailComposController (_ controller: MFMailComposViewController, 结果: MFMailComposResult,Error: Swift. Error?){
controller.dismiss(animated: true, completion: nil) }