Reputation: 16416
I have a MFMailComposeViewController setup and presented as such:
class MyViewController: UIViewController {
// MARK: - Properties
let composeViewController = MFMailComposeViewController()
// MARK: - Actions
@IBAction func didTapSendInEmailButton() {
composeViewController.mailComposeDelegate = self
composeViewController.setToRecipients([Constants.contactRecipientEmail])
composeViewController.setSubject(Constants.contactSubject)
composeViewController.setMessageBody(Constans.body, isHTML: false)
present(composeViewController, animated: true, completion: nil)
}
}
// MARK: - MFMailComposeViewControllerDelegate
extension MyViewController: MFMailComposeViewControllerDelegate {
private func mailComposeController(_ controller: MFMailComposeViewController,
didFinishWith result: MFMailComposeResult,
error: Error?) {
switch result {
case .sent:
print("Email sent")
case .saved:
print("Draft saved")
case .cancelled:
print("Email cancelled")
case .failed:
print("Email failed")
}
controller.dismiss(animated: true, completion: nil)
}
}
I'm having this issue:
What may I be missing?
I'm not able to declare mailComposeController as public:
Upvotes: 2
Views: 1464
Reputation: 36610
A few minor changes that I will highlight in comments:
import UIKit
import MessageUI
class MyViewController: UIViewController {
// MARK: - Properties
let composeViewController = MFMailComposeViewController()
// MARK: - Actions
@IBAction func didTapSendInEmailButton() {
composeViewController.mailComposeDelegate = self
// Entered a generic email in place of your constant value
composeViewController.setToRecipients(["[email protected]"])
// Entered a generic subject in place of your constant value
composeViewController.setSubject("subject")
// You have a typo on "Constants" here
composeViewController.setMessageBody("body", isHTML: false)
present(composeViewController, animated: true, completion: nil)
}
}
// MARK: - MFMailComposeViewControllerDelegate
extension MyViewController: MFMailComposeViewControllerDelegate {
// Removed the private
func mailComposeController(_ controller: MFMailComposeViewController,
didFinishWith result: MFMailComposeResult,
error: Error?) {
switch result {
case .sent:
print("Email sent")
case .saved:
print("Draft saved")
case .cancelled:
print("Email cancelled")
case .failed:
print("Email failed")
}
controller.dismiss(animated: true, completion: nil)
}
}
And my console log shows email sent.
Have you confirmed that your Constants object contains valid data? Perhaps you should print it out or view it at a breakpoint when it arrives here to ensure there are no issues with its contents.
Also, make sure you have a valid email account set up on your device in the first place to send the email for you. If it is a development device, then it may have been reset and lost at some point.
Comparing the Error type in yours:
Notice that the color of Error
changes. This means it is using an Error that you have defined, which is scoped to private. You need to break this by renaming your Error to something else. Once that is done, it should resolve your error.
Upvotes: 4
Reputation: 3708
I have also face similar issue recently, My work around is i moved the declaration inside button action
class MyViewController: UIViewController {
// MARK: - Actions
@IBAction func didTapSendInEmailButton() {
let composeViewController = MFMailComposeViewController()
composeViewController.mailComposeDelegate = self
composeViewController.setToRecipients([Constants.contactRecipientEmail])
composeViewController.setSubject(Constants.contactSubject)
composeViewController.setMessageBody(Constans.body, isHTML: false)
present(composeViewController, animated: true, completion: nil)
}
}
// MARK: - MFMailComposeViewControllerDelegate
extension MyViewController: MFMailComposeViewControllerDelegate {
func mailComposeController(_ controller: MFMailComposeViewController,
didFinishWith result: MFMailComposeResult,
error: Error?) {
switch result {
case .sent:
print("Email sent")
case .saved:
print("Draft saved")
case .cancelled:
print("Email cancelled")
case .failed:
print("Email failed")
}
controller.dismiss(animated: true, completion: nil)
}
}
Also you don't need to make delegate method private
Upvotes: 2
Reputation: 6067
I don't know where is your problem
i test Your code it works nice , compiler not in-force me to set delegate as private , Note Email composer not work on simulator
just on device
import UIKit
import MessageUI
class MyViewController: UIViewController {
// MARK: - Properties
let composeViewController = MFMailComposeViewController()
// MARK: - Actions
@IBAction func didTapSendInEmailButton() {
if MFMailComposeViewController.canSendMail() {
composeViewController.mailComposeDelegate = self
composeViewController.setToRecipients(["[email protected]"])
composeViewController.setSubject("Constants.contactSubjec")
composeViewController.setMessageBody("Constans.body", isHTML: false)
present(composeViewController, animated: true, completion: nil) } else {
}
}
}
// MARK: - MFMailComposeViewControllerDelegate
extension MyViewController: MFMailComposeViewControllerDelegate {
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
switch result {
case .sent:
print("Email sent")
case .saved:
print("Draft saved")
case .cancelled:
print("Email cancelled")
case .failed:
print("Email failed")
}
controller.dismiss(animated: true, completion: nil)
}
}
Upvotes: 2
Reputation:
extension MyViewController: MFMailComposeViewControllerDelegate {
private func mailComposeController(_ controller: MFMailComposeViewController,
didFinishWith result: MFMailComposeResult,
error: Error?)
Check your delegate method again, it should be public
.
Also make sure your mail account is configured properly.
Upvotes: 2