用Swift 3发送电子邮件

55

我正在尝试设置一个带有发送电子邮件选项的应用程序。

这是我的代码:

import Foundation
import MessageUI
import UIKit

class emailClass: UIViewController, MFMailComposeViewControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()

        if !MFMailComposeViewController.canSendMail() {
            print("Mail services are not available")
            return
        }        
        sendEmail() 
    }

    func sendEmail() {      
        let composeVC = MFMailComposeViewController()
        composeVC.mailComposeDelegate = self
        // Configure the fields of the interface.
        composeVC.setToRecipients(["address@example.com"])
        composeVC.setSubject("Hello!")
        composeVC.setMessageBody("Hello this is my message body!", isHTML: false)
        // Present the view controller modally.
        self.present(composeVC, animated: true, completion: nil)
    }

    func mailComposeController(controller: MFMailComposeViewController,
                           didFinishWithResult result: MFMailComposeResult, error: NSError?) {
        // Check the result or perform other tasks.
        // Dismiss the mail compose view controller.
        controller.dismiss(animated: true, completion: nil)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

所以我收到了这个消息:"邮件服务不可用"。现在我已经登陆iCloud模拟器设备了......所以我认为它应该可以,但是它没有。为什么它不能工作?你能告诉我问题出在哪里,以及我该如何继续吗?


你是否已经在设备上配置了电子邮件地址?如果没有,那么请进行配置...这可能会解决你的问题。 - dev_binod
我正在使用模拟器。如何配置设备的电子邮件地址?当我进入设置时,我看不到“电子邮件”选项... - H.N.
我觉得你已经解决了这个问题。同时,这里有一个链接,可以配置iOS设备的电子邮件... https://support.apple.com/zh-cn/HT201320 - dev_binod
100% 工作和测试过的。在这里,https://dev59.com/j1oV5IYBdhLWcg3wAqvy#49169455 - Mr.Javed Multani
5个回答

49

是的,我100%确定。我正在开发同类型的应用程序,并找到了这个。 - SandeepM
好的,谢谢 :) 但是我上面写的代码,可以吗? - H.N.
是的。代码看起来没问题,应该可以工作。你没有 iPhone 吗? - SandeepM

39

以下是我的做法。看起来你已经很好地遵循了文档,但我想提供我的一些变化,以防对其他人有所帮助。此外,这个方法对当前的(2017年8月)语法进行了一些更新。

遵循MFMailComposeViewControllerDelegate协议,并检查设备是否可以发送电子邮件。

import Foundation
import UIKit
import MessageUI

class WelcomeViewController: UIViewController, MFMailComposeViewControllerDelegate {


override func viewDidLoad() {
    super.viewDidLoad()

    if !MFMailComposeViewController.canSendMail() {
        print("Mail services are not available")
        return
    }
}

我的应用使用一个IBAction来启动邮件组合。

@IBAction func sendFeedbackButtonTapped(_ sender: Any) {

    let composeVC = MFMailComposeViewController()
    composeVC.mailComposeDelegate = self

    // Configure the fields of the interface.
    composeVC.setToRecipients(["exampleEmail@email.com"])
    composeVC.setSubject("Message Subject")
    composeVC.setMessageBody("Message content.", isHTML: false)

    // Present the view controller modally.
    self.present(composeVC, animated: true, completion: nil)

}
关于下面的mailComposeController函数,文档中指出:
邮件撰写视图控制器不会自动关闭。当用户点击发送邮件或取消界面按钮时,邮件撰写视图控制器会调用其委托的mailComposeController(_:didFinishWith:error:)方法。您必须显式地实现该方法以关闭视图控制器,如列表3所示。您还可以使用此方法来检查操作的结果。
func mailComposeController(_ controller: MFMailComposeViewController,
                           didFinishWith result: MFMailComposeResult, error: Error?) {
    // Check the result or perform other tasks.

    // Dismiss the mail compose view controller.
    controller.dismiss(animated: true, completion: nil)
   }
}

来源 Apple文档:MFMailComposeViewController


1
为了强调会导致问题的事情:在旧版本中,...didFinishWith result:...头文件中error:的类型是NSError?。在新版本中,它只是Error?。如果您的委托没有与预期的完全相同的头文件,则您的委托将无法正常工作--关闭视图控制器的代码部分将不会运行,并且邮件将保留在其他视图的顶部。我花了很长时间才发现这个微小的差异;希望这可以帮助某些人。 - ConfusionTowers

13

在Swift 5中发送电子邮件非常容易,您需要确认并实现MFMailComposeViewControllerDelegate,并检查是否可以在此设备上发送电子邮件

这是我用于我的任务的小代码片段

import UIKit
import MessageUI

class ViewController: UIViewController, MFMailComposeViewControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    //MARK: IBAction Method for Button click
    @IBAction func sendEmail(_ sender: Any) {
        //TODO:  You should chack if we can send email or not
        if MFMailComposeViewController.canSendMail() {
            let mail = MFMailComposeViewController()
            mail.mailComposeDelegate = self
            mail.setToRecipients(["you@yoursite.com"])
            mail.setSubject("Email Subject Here")
            mail.setMessageBody("<p>You're so awesome!</p>", isHTML: true)
            present(mail, animated: true)
        } else {
            print("Application is not able to send an email")
        }
    }

    //MARK: MFMail Compose ViewController Delegate method
    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        controller.dismiss(animated: true)
    }
}

提示:请不要忘记在真实设备上测试此内容。


9

如果应用在真实设备上运行,代码看起来很好并且能够正常工作。

MFMailComposeViewController.canSendMail() // returns false for simulators.

你不能在模拟器上进行测试,你只能测试基本的东西,例如UI界面以及在取消/发送按钮点击时发生的事情。

要进行测试,必须使用设备,在设备中配置邮箱应用程序并添加一些邮件地址(例如abc@xyz.com)。

希望这有所帮助。


1
您的代码问题在于,

//以模态形式呈现视图控制器。 self.present(composeVC, animated: true, completion: nil)

它在自身中呈现;-)

如果您不知道当前的视图控制器,只需将其显示在RootViewController上,例如

UIApplication.shared.keyWindow?.rootViewController?.present(...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接