4

I have a problem with MFMailComposeViewControllerDelegate function.

func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    controller.dismiss(animated: true, completion: nil)
}

The warning says

Instance method 'mailComposeController(:didFinishWith:error:)' nearly matches optional requirement 'mailComposeController(:didFinishWith:error:)' of protocol 'MFMailComposeViewControllerDelegate'

Make 'mailComposeController(_:didFinishWith:error:)' private to silence this warning

I need to return the user to the App and dismiss MFMailComposeViewController after clicking cancel and this function is not triggered.

Yes, I added the delegate composeVC.mailComposeDelegate = self

If someone had a similar problem, I would appreciate the help. Thanks

EDIT

This behavior is happening only when I set the language to Swift 4. I just went back few commits and it's working perfectly fine with Swift 3.2

Basically, this is the code:

class TechSupportVC: UIViewController, MFMailComposeViewControllerDelegate {
    let composeVC = MFMailComposeViewController()

override func viewDidLoad() {
    super.viewDidLoad()

    composeVC.mailComposeDelegate = self
    composeVC.setToRecipients(["desiredEmail@gmail.com"])
    composeVC.setSubject("My message")
}

func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    controller.dismiss(animated: true, completion: nil)
}

@IBAction func sendPressed(_ sender: Any) {
    guard MFMailComposeViewController.canSendMail() else {
        showMailServiceErrorAlert()
        return
    }

    composeVC.setMessageBody("Test credentials: \(firstAndLastNameTextField.text!)\nPhone: \(numberTextField.text!)\n\n\(messageTextView.text!)", isHTML: false)

    self.present(composeVC, animated: true, completion: nil)
}

}

Đorđe Nilović
  • 3,600
  • 1
  • 25
  • 20
  • Try to delete the function, start typing it in and let Xcode autocomplete it. – Tamás Sengel Feb 09 '18 at 10:01
  • @the4kman I did it already and that's the only autocomplete I'm getting. – Đorđe Nilović Feb 09 '18 at 10:07
  • Did you checked if MFMailComposeViewController.canSendMail() before presenting the mail – Shehata Gamal Feb 09 '18 at 10:11
  • @Sh_Khan Of course, the code in this class is pretty simple. It seems like everything is fine except not triggering this function. – Đorđe Nilović Feb 09 '18 at 10:18
  • @Đorđe Nilović, try to check you project settings (Project -> Build settings -> swift compiler - language) – Grigory Konovalov Feb 09 '18 at 10:19
  • @GrigoryKonovalov This was written in Swift 3 and it was working just fine, definitely a strange behavior now when I did a conversion to Swift 4. :) Language Version is set to Swift 4.0 – Đorđe Nilović Feb 09 '18 at 10:26
  • @Đorđe Nilović, it looks strange. Seems you have a bug there. Did you try to rewrithe the method totally? – Grigory Konovalov Feb 09 '18 at 10:29
  • @Krunal I just updated my question. Thanks – Đorđe Nilović Feb 09 '18 at 10:45
  • 1
    @ĐorđeNilović I tested you code in Xcode 9.3 beta2 and Swift 4. It's working fine without any error or warning message. You don't have problem with the code. Remove MessageUI Framework and add again in your project. – Krunal Feb 09 '18 at 10:49
  • 1
    @Krunal I just checked with a new project and it's working as well. I did reset the changes that Xcode did while doing a conversion to Swift 4 and I did it manually. Now it's working. To be honest, I have no idea what happened, I can only suspect that Xcode conversion "damaged" somehow MessageUI Framework. Thank you for your time and advice! – Đorđe Nilović Feb 09 '18 at 14:32
  • 1
    @ĐorđeNilović Answer your question, with steps you have followed to solve this problem. It will be helpful to other in future. You can also, accept your own answer, after a day. :) – Krunal Feb 09 '18 at 14:34

3 Answers3

12

It wasn't possible for me to apply Đorđe's solution, this other answer helped me.

func mailComposeController(_ controller: MFMailComposeViewController,
                           didFinishWith result: MFMailComposeResult,
                           error: Swift.Error?) {
    controller.dismiss(animated: true, completion: nil)
}

Adding Swift. prefix to Error? solves the problem.

Boris Y.
  • 4,387
  • 2
  • 32
  • 50
  • I just edited my answer and described the reason for my particular problem. Thanks – Đorđe Nilović Feb 14 '18 at 12:38
  • Spent hours on trying to figuring this one out. Using Swift.Error fixed it! Thanks! My guess is that, depending on how your project is set up and what modules you import, some other type named Error shadows the Swift.Error type. – ntherning Aug 25 '20 at 06:30
3

I had the same issue where the mailComposeControler delegate wasn't getting called after canceling or sending the mail. xCode gave me the same warning about adding private. I did not have an issue an enumeration named Error as the others had.

The only way I could fix it was to specifically define the function as public.

public func mailComposeController(_ controller: MFMailComposeViewController,
                                  didFinishWith result: MFMailComposeResult, error: Error?) {
    // Check the result or perform other tasks.

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

After doing that it worked fine.

This was in Swift 4.0, xCode 10.1.

jeffjv
  • 3,461
  • 2
  • 21
  • 28
0

EDIT:

After adding other classes to the project I encountered the same problem again and realized that conversion was not the problem.

The problem was that I have an enumeration named Error, that's why the parameter error: was not recognizing the Swift Error class, so the warning was correct.

I came to edit the answer and I saw that Boris Y. wrote the fix for this, so I'll accept his answer.

Đorđe Nilović
  • 3,600
  • 1
  • 25
  • 20