【问题标题】:MFMailComposeViewController in SwiftSwift 中的 MFMailComposeViewController
【发布时间】:2014-08-10 06:08:00
【问题描述】:

这是示例代码:

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 表达式都会出错:

找不到接受所提供参数的重载“~=”。

我做错了什么?

【问题讨论】:

  • 您是否尝试过将switch 案例转换为Swift-conform?像case MFMailComposeResult.Cancelled: 等等...?我在 Swift 中找不到关于这个 enum 的参考资料,所以我的想法宁愿是一个问题而不是一个纯粹的解决方案。
  • 刚试过:MFMailComposeResult.Type 没有名为 'Canceled' 的成员等
  • 提示:应尽可能使用let 而不是var

标签: objective-c uiviewcontroller swift ios8 mfmailcomposer


【解决方案1】:

我比较了 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函数不起作用,两个按钮——“发送”和“取消”,变成了灰色,所以一直存在。怎么了?
  • 从第一个测试版开始似乎是一个错误,你可以看到它here
  • @AudreySobgouZebaze。您将 MFComposeResult 作为 iOS8 中的结构和 iOS7 中的枚举的关联并不完全正确。 MFMailComposeResult 是 Objective-C 中的一个枚举,现在它是 Swift 中的一个结构(无论操作系统版本或 SDK:iOS 7/iOS 8)... e
  • 在 Swift 2.1+ 中使用 "rawValue" (UInt32) 而不是 "value"
【解决方案2】:

在 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)
    }

【讨论】:

    【解决方案3】:

    在 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)
    }
    

    【讨论】:

      【解决方案4】:

      在 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)
      
          }
      

      【讨论】:

        【解决方案5】:

        除了使用.value之外,别忘了在每个case声明中添加break,查看苹果官方版本:https://developer.apple.com/library/iOS/samplecode/MessageComposer/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010161

        【讨论】:

        • Swift 不需要中断
        猜你喜欢
        • 2014-08-12
        • 1970-01-01
        • 2016-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多