Swift中的MFMailComposeViewController

31

这是示例代码:

import UIKit
import MessageUI

class ViewController: UIViewController, MFMailComposeViewControllerDelegate {

    @IBAction func showEmail(sender : AnyObject) {
        var emailTitle = "Test Email"
        var messageBody = "This is a test email body"
        var toRecipents = ["a.nakhimov@gmail.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)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    func mailComposeController(controller:MFMailComposeViewController, didFinishWithResult result:MFMailComposeResult, error:NSError) {
        switch result {
        case MFMailComposeResultCancelled:
            NSLog("Mail cancelled")
        case MFMailComposeResultSaved:
            NSLog("Mail saved")
        case MFMailComposeResultSent:
            NSLog("Mail sent")
        case MFMailComposeResultFailed:
            NSLog("Mail sent failure: %@", [error.localizedDescription])
        default:
            break
        }
        self.dismissViewControllerAnimated(false, completion: nil)
    }
}
在函数mailComposeController中,每个case表达式都会出现错误:Could not find an overload '~=' that accepts the supplied arguments.。我做错了什么?

1
你尝试过将switch语句转换为符合_Swift_标准的格式吗?比如case MFMailComposeResult.Cancelled:等等?我无法在_Swift_中找到有关此枚举的相关参考资料,所以我的想法更像是一个问题而不是完整的解决方案。 - holex
1
刚试了一下:MFMailComposeResult.Type 没有名为“Canceled”的成员,等等。 - Alexey Nakhimov
提示:在可能的情况下,应该使用 let 而不是 var - David
5个回答

33

我在Xcode 5和Xcode 6上比较了MFMailComposeResult的文档。 在Swift中,MFMailComposeResult是一个结构体。

struct MFMailComposeResult {
    init(_ value: CUnsignedInt) // available in iPhone 3.0
    var value: CUnsignedInt
}

MFMailComposeResultCancelled作为MFMailComposeResult类型的常量:

var MFMailComposeResultCancelled: MFMailComposeResult { get }

虽然在Objective-C中它是一个枚举:

 enum MFMailComposeResult {
    MFMailComposeResultCancelled,
    MFMailComposeResultSaved,
    MFMailComposeResultSent,
    MFMailComposeResultFailed
};
typedef enum MFMailComposeResult MFMailComposeResult;   // available in iPhone 3.0
为了使您的代码运行,您将需要比较它们的值,这些值是 CUnsignedInt
因此,您将需要键入以下代码:
func mailComposeController(controller:MFMailComposeViewController, didFinishWithResult result:MFMailComposeResult, error:NSError) {
    switch result.value {
    case MFMailComposeResultCancelled.value:
        println("Mail cancelled")
    case MFMailComposeResultSaved.value:
        println("Mail saved")
    case MFMailComposeResultSent.value:
        println("Mail sent")
    case MFMailComposeResultFailed.value:
        println("Mail sent failure: \(error.localizedDescription)")
    default:
        break
    }
    self.dismissViewControllerAnimated(false, completion: nil)
}

当我点击按钮时,函数showEmail被执行并出现了发送邮件的表单。如果我点击“发送”,那么一切都正常 - 邮件被发送,然后执行函数mailComposeController。 NSLog显示标签“邮件已发送”,初始屏幕重新出现。如果我在发送邮件的对话框中,点击“取消”按钮,那么对话框不会消失,函数mailComposeController不起作用,“发送”和“取消”两个按钮变成灰色,一直保持这样。怎么了? - Alexey Nakhimov
自从第一个beta版本以来,似乎存在一个bug,你可以在这里看到它。 - Audrey Sobgou Zebaze
@AudreySobgouZebaze。您在iOS8中将MFComposeResult定义为结构体,而在iOS7中定义为枚举的说法并不完全正确。MFMailComposeResult在Objective-C中是一个枚举,在Swift中它现在是一个结构体(无论操作系统版本或SDK:iOS 7/iOS 8)... - eharo2
1
在Swift 2.1+中,请使用“rawValue”(UInt32)代替“value”。 - Sean Dev

19

在 Swift 2.0 中要这样做:

func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?) {
        switch result.rawValue {
        case MFMailComposeResultCancelled.rawValue:
            print("Mail cancelled")
        case MFMailComposeResultSaved.rawValue:
            print("Mail saved")
        case MFMailComposeResultSent.rawValue:
            print("Mail sent")
        case MFMailComposeResultFailed.rawValue:
            print("Mail sent failure: \(error!.localizedDescription)")
        default:
            break
        }
        controller.dismissViewControllerAnimated(true, completion: nil)
    }

6
在Swift 3.0中,语法发生了变化。
func mailComposeController(controller: MFMailComposeViewController,
                           didFinishWithResult result: MFMailComposeResult, error: NSError?) {

    switch result.rawValue {
    case MFMailComposeResult.Cancelled.rawValue:
        print("Mail cancelled")
    case MFMailComposeResult.Saved.rawValue:
        print("Mail saved")
    case MFMailComposeResult.Sent.rawValue:
        print("Mail sent")
    case MFMailComposeResult.Failed.rawValue:
        print("Mail sent failure: %@", [error!.localizedDescription])
    default:
        break
    }
    // Dismiss the mail compose view controller.
    controller.dismissViewControllerAnimated(true, completion: nil)
}

1
在 Swift 3 中,你可以使用以下清晰的代码:
 @IBAction func sendMail(_ sender: Any) {

        print(MFMailComposeViewController.canSendMail())
        if MFMailComposeViewController.canSendMail() {
            let mail = MFMailComposeViewController()
            mail.mailComposeDelegate = self
            mail.setToRecipients(["test@test.com"])
            mail.setMessageBody("<p>This is test Mail!</p>", isHTML: true)

            present(mail, animated: true)
        } else {
             let email = "test@test.com"
             if let url = URL(string: "mailto:\(email)") {
             UIApplication.shared.open(url)
             }

        }


    }

    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        controller.dismiss(animated: true)
        switch result {
        case .cancelled:
            print("Mail cancelled")
        case .saved:
            print("Mail saved")
        case .sent:
            self.allertInfo(_title: "Mail Info", _message: "Mail is sent successfuly", _actionTitle: "OK")
            print("Mail sent")
        case .failed:
            self.allertInfo(_title: "Mail Info", _message: "Mail isn't sent.",
_actionTitle: "OK")
            print("Mail sent failure: \(error?.localizedDescription)")
        default:
            break
        }

    }

    func allertInfo(_title:String, _message:String, _actionTitle:String) {

        let alert = UIAlertController(title: _title, message: _message, preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction(UIAlertAction(title: _actionTitle, style: UIAlertActionStyle.default, handler: nil))
        self.present(alert, animated: true, completion: nil)

    }

-7

7
Swift 不需要使用 break。 - Yariv Nissim

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