7
votes

I found this source code from here and tried sending mail using it. I successfully got the 'MFMailComposeResultSent' Message, but actual mail is not sent. I don't understand why is not working. Also, I attached an image from NSData, but it doesn't display in mailcomposeview. What is the wrong with this code? Actually, I only need calling native mail app with an attachement image, but I heard there is no way calling the native app with attachement. Please let me know what is wrong with my code. Problem 1: doesn't send a mail from mailcomposeview, Problem 2: doesn't display attached image. Best : running native mail app with attached image. I'll be happily waiting your answers. Thx.

-(void) sendMail
{
NSLog(@"Mail");
MFMailComposeViewController *mfMailView = [[MFMailComposeViewController alloc]init];
NSData *imgData = UIImagePNGRepresentation(imgPreview.image);
mfMailView.mailComposeDelegate = self;

[mfMailView addAttachmentData:imgData mimeType:@"image/png" fileName:@"Me.png"];

//also tried this
//[mfMailView addAttachmentData:imgData mimeType:@"image/png" fileName:@"Me"];

[mfMailView setSubject:@"TE~st"];

[mfMailView setMessageBody:@"Download Me~!" isHTML:YES];
[self presentModalViewController:mfMailView animated:YES];
}

-(void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result) {
    case MFMailComposeResultCancelled:
        NSLog(@"cancel?");
        break;
    case MFMailComposeResultSaved:
        NSLog(@"saved?");
        break;
    case MFMailComposeResultSent:
        NSLog(@"Sent succed");
        [controller dismissModalViewControllerAnimated:YES];
        break;
    case MFMailComposeResultFailed:
        NSLog(@"sent failue");
        NSLog(@"%@",error);
        break;
    default:
        break;
}
}
3
are you sending via simulator or on your device?shabbirv
Is your device on the network? I think when you get MFMailComposeResultSent, it actually means it has successfully told the mail app to send the email, but it might actually be queued to be sent and waiting if you don't have network.Stew
@shabzco. Is it possible to send using simulator?Gajendra K Chauhan

3 Answers

4
votes
  1. Make sure that you have an account configured in the settings.
  2. I didn't find any recipient??

You can take a reference from this link.

0
votes

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(["[email protected]"])
            mail.setMessageBody("<p>This is test Mail!</p>", isHTML: true)

            present(mail, animated: true)
        } else {
             let email = "[email protected]"
             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)

    }
0
votes

Swift 5 and Xcode 12.5.1 ....

Open config mail if exist or go to other options ...

Declare the feedback mail

let recipientEmail = "[email protected]"

On Click Event

      @IBAction func openEmail(_ sender: Any) {
        
        if MFMailComposeViewController.canSendMail() {
            self.sendEmail(title: "Subject")
        } else {
            if let emailUrl = createEmailUrl(to: recipientEmail,
                                             subject: "Subject", body: "Send from my iPhone") {
                UIApplication.shared.open(emailUrl)
            }
        }
    }


func sendEmail(title : String){
    let EmialVC = configuredMailForWriteWithUs(title: title)
    self.present(EmialVC, animated: true, completion: nil)
}

       private func createEmailUrl(to: String, subject: String, body: String) -> URL? {
           let subjectEncoded = subject.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
           let bodyEncoded = body.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!

           let gmailUrl = URL(string: "googlegmail://co?to=\(to)&subject=\(subjectEncoded)&body=\(bodyEncoded)")
           let outlookUrl = URL(string: "ms-outlook://compose?to=\(to)&subject=\(subjectEncoded)")
           let yahooMail = URL(string: "ymail://mail/compose?to=\(to)&subject=\(subjectEncoded)&body=\(bodyEncoded)")
           let sparkUrl = URL(string: "readdle-spark://compose?recipient=\(to)&subject=\(subjectEncoded)&body=\(bodyEncoded)")
           let defaultUrl = URL(string: "mailto:\(to)?subject=\(subjectEncoded)&body=\(bodyEncoded)")

           if let gmailUrl = gmailUrl, UIApplication.shared.canOpenURL(gmailUrl) {
               return gmailUrl
           } else if let outlookUrl = outlookUrl, UIApplication.shared.canOpenURL(outlookUrl) {
               return outlookUrl
           } else if let yahooMail = yahooMail, UIApplication.shared.canOpenURL(yahooMail) {
               return yahooMail
           } else if let sparkUrl = sparkUrl, UIApplication.shared.canOpenURL(sparkUrl) {
               return sparkUrl
           }

           return defaultUrl
       }

If the user doesn't have any mail config it's gonna ask for others mail options...