31

This is sample code:

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

In function mailComposeController I get an error on every case expression:

Could not find an overload '~=' that accepts the supplied arguments.

What am I doing wrong?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Alexey Nakhimov
  • 2,673
  • 8
  • 34
  • 49
  • 1
    have you tried to convert the `switch` cases into _Swift_-conform? like `case MFMailComposeResult.Cancelled:` ect...? I could not find the reference about this `enum` in _Swift_, so my idea would rather be a question than a pure solution. – holex Jun 19 '14 at 16:24
  • 1
    Just tried: MFMailComposeResult.Type does not have a member named 'Canceled', etc. – Alexey Nakhimov Jun 19 '14 at 16:27
  • hint: wherever possible one should use `let` instead of `var` – David Oct 18 '14 at 10:09

5 Answers5

33

I compared MFMailComposeResult documentation on both Xcode 5 and Xcode 6. In Swift, MFMailComposeResult is a struct

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

with MFMailComposeResultCancelled as a constant of type MFMailComposeResult:

var MFMailComposeResultCancelled: MFMailComposeResult { get }

while it's an enum in Objective-C:

 enum MFMailComposeResult {
    MFMailComposeResultCancelled,
    MFMailComposeResultSaved,
    MFMailComposeResultSent,
    MFMailComposeResultFailed
};
typedef enum MFMailComposeResult MFMailComposeResult;   // available in iPhone 3.0

In order to make your code work, you will have to compare their values which are CUnsignedInt.

So you will have to type the following code:

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)
}
Rob Keniger
  • 45,830
  • 6
  • 101
  • 134
Audrey Sobgou Zebaze
  • 2,840
  • 2
  • 19
  • 9
  • When I push the button, the function showEmail is executed and appears the form for send email. If I click "Send", then everything works fine - mail is sent, then the function mailComposeController is executed. NSLog displays the label "Mail sent" and the initial screen reappears. If I'm in the dialog box of send mail, click "Cancel" button, then dialogue does not disappear, function mailComposeController does not work, two buttons - "Send" and "Cancel", becoming gray color and so it stays. What wrong? – Alexey Nakhimov Jun 21 '14 at 13:04
  • It seems to be a bug since first beta, you can see it [here](http://stackoverflow.com/questions/24218708/cant-dismiss-mfmailcomposeviewcontroller-shown-by-clicking-mail-link-in-uitextvi?rq=1) – Audrey Sobgou Zebaze Jun 22 '14 at 13:25
  • @AudreySobgouZebaze. Your association of MFComposeResult as struct in iOS8 and enum in iOS7 is not quite correct. MFMailComposeResult is an enum in Objective-C and it is now a struct in Swift (regardless of the OS version, or SDK: iOS 7/iOS 8)... e – eharo2 Aug 01 '14 at 17:47
  • 1
    In Swift 2.1+ use "rawValue" (UInt32) instead of "value" – Sean Dev Apr 11 '16 at 11:25
19

in Swift 2.0 do this:

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)
    }
David
  • 231
  • 3
  • 3
6

In swift 3.0 -> Syntax Change

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)
}
C0mrade
  • 1,215
  • 1
  • 10
  • 23
Dipang
  • 1,111
  • 12
  • 12
1

In swift 3, you can use this clear code:

 @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)

    }
Yasin Ugurlu
  • 691
  • 5
  • 11
-7

In addition to using .value, don't forget to add to break to each case statement, see Apple's official version: https://developer.apple.com/library/iOS/samplecode/MessageComposer/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010161

netwire
  • 7,108
  • 12
  • 52
  • 86