14

Hello i want to open the eMail program from my App and the body should already be defined. I can open the eMail but don't know how to define the body of the eMail as a given Parameter to show a given standard text. Anyone can help? Heres the code i use to open Email:

//EMAIL
let email = "foo@bar.com"
let urlEMail = NSURL(string: "mailto:\(email)")

if UIApplication.sharedApplication().canOpenURL(urlEMail!) {
                UIApplication.sharedApplication().openURL(urlEMail!)
} else {
print("Ups")
}
Stefan
  • 5,203
  • 8
  • 27
  • 51
JanScott
  • 265
  • 1
  • 5
  • 14
  • Do some research on the `mailto:` URL scheme. You can provide "to" addresses, "cc" addresses, a subject, and the message body. But of course the best option is to do what the answers below suggest. – rmaddy Nov 13 '15 at 14:53

10 Answers10

30

If you'd like to open the built-in email app as opposed to showing the MFMailComposeViewController as has been mentioned by others, you could construct a mailto: link like this:

let subject = "My subject"
let body = "The awesome body of my email."
let encodedParams = "subject=\(subject)&body=\(body)".stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet())
let url = "mailto:foo@bar.com?\(encodedParams)"

if let emailURL = NSURL(url) {
    if UIApplication.sharedApplication().canOpenURL(emailURL) {
        UIApplication.sharedApplication().openURL(emailURL)
    }
}

Just to save anyone typing, for 2016 the syntax has changed slightly:

let subject = "Some subject"
let body = "Plenty of email body."
let coded = "mailto:blah@blah.com?subject=\(subject)&body=\(body)".stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet())

if let emailURL:NSURL = NSURL(string: coded!)
    {
    if UIApplication.sharedApplication().canOpenURL(emailURL)
        {
        UIApplication.sharedApplication().openURL(emailURL)
        }
Fattie
  • 27,874
  • 70
  • 431
  • 719
mclaughj
  • 12,645
  • 4
  • 31
  • 37
25

Swift 3 Version

let subject = "Some subject"
let body = "Plenty of email body."
let coded = "mailto:blah@blah.com?subject=\(subject)&body=\(body)".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)

if let emailURL: NSURL = NSURL(string: coded!) {
    if UIApplication.shared.canOpenURL(emailURL as URL) {
        UIApplication.shared.openURL(emailURL as URL)
    }
}
Matthew Barker
  • 638
  • 9
  • 13
17

You can do it using MFMailComposeViewController:

import MessageUI

let mailComposerVC = MFMailComposeViewController()
mailComposerVC.mailComposeDelegate = self
mailComposerVC.setToRecipients(["email@email.com"])
mailComposerVC.setSubject("Subject")
mailComposerVC.setMessageBody("Body", isHTML: false)
self.presentViewController(mailComposerVC, animated: true, completion: nil)

Also, you need to implement mailComposeController:didFinishWithResult:error: from MFMailComposeViewControllerDelegate where you should dismiss MFMailComposeViewController

Developeder
  • 1,579
  • 18
  • 29
  • 6
    Before you create your mailComposerVC it is not a bad idea to check if you actually can send an email using `MFMailComposeViewController.canSendMail()` – Au Ris May 02 '17 at 13:18
11

Swift 4.0

    let email = "feedback@company.com"
    let subject = "subject"
    let bodyText = "Please provide information that will help us to serve you better"
    if MFMailComposeViewController.canSendMail() {
        let mailComposerVC = MFMailComposeViewController()
        mailComposerVC.mailComposeDelegate = self
        mailComposerVC.setToRecipients([email])
        mailComposerVC.setSubject(subject)
        mailComposerVC.setMessageBody(bodyText, isHTML: true)
        self.present(mailComposerVC, animated: true, completion: nil)
    } else {
        let coded = "mailto:\(email)?subject=\(subject)&body=\(bodyText)".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
        if let emailURL = URL(string: coded!)
        {
            if UIApplication.shared.canOpenURL(emailURL)
            {
                UIApplication.shared.open(emailURL, options: [:], completionHandler: { (result) in
                    if !result {
                        // show some Toast or error alert
                        //("Your device is not currently configured to send mail.")
                    }
                })
            }
        }
    }
Manish Nahar
  • 834
  • 10
  • 24
4

Use the MFMailComposeViewController like this:

  1. Import the MessageUI

    import MessageUI
    
  2. Add the delegate to your class:

    class myClass: UIViewController, MFMailComposeViewControllerDelegate {}
    
  3. Configure the email preset you want to have

    let mail = MFMailComposeViewController()
    mail.mailComposeDelegate = self
    mail.setSubject("Subject")
    mail.setMessageBody("Body", isHTML: true)
    mail.setToRecipients(["my@email.com"])
    presentViewController(mail, animated: true, completion: nil)
    
  4. Put this method in your code:

    func mailComposeController(controller: MFMailComposeViewController!, didFinishWithResult result: MFMailComposeResult, error: NSError!) {
        dismissViewControllerAnimated(true, completion: nil)
    }
    

There you go, works now.

LinusGeffarth
  • 27,197
  • 29
  • 120
  • 174
2

Updated for Xcode 12.5

let url = NSURL(string: "mailto:mailto:someone@example.com")
                                            UIApplication.shared.open(url! as URL)

or if you would like to add an embedded subject

let url = NSURL(string: "mailto:someone@example.com?subject=This%20is%20the%20subject&cc=someone_else@example.com&body=This%20is%20the%20body")

or if you want to add multiple email addresses

let url = NSURL(string: "mailto:mailto:someone@example.com,someoneelse@example.com")
                                                UIApplication.shared.open(url! as URL)
flutterloop
  • 546
  • 3
  • 15
1

Similar to url construction in the other answers, but instead of calling addingPercentEncoding you can use URLComponents:

var components = URLComponents(string: "youremail@test.com")
components?.queryItems = [URLQueryItem(name: "subject", value: "Your Subject")]

if let mailUrl = components?.url {
    UIApplication.shared.open(mailUrl, options: [:], completionHandler: nil)
}
Ivy Xing
  • 284
  • 2
  • 8
1

Swift 5 version of @mclaughj answer

let email = "foo@bar.com"
let subject = "Your Subject"
let body = "Plenty of email body."
            
let coded = "mailto:\(email)?subject=\(subject)".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
    
if let emailURL:NSURL = NSURL(string: coded!)
       {
          if UIApplication.shared.canOpenURL(emailURL as URL){
             UIApplication.shared.open(emailURL as URL)
          }
       }

Cheers!

teja_D
  • 383
  • 3
  • 18
0

I suggest to use Apple's way, which you can find in official documentation about MFMailComposeViewController. It opens a modal view controller with the email, which is dismissed after sending. Thus user stays in your app.

David Rysanek
  • 901
  • 12
  • 16
  • 1
    OP asked for Swift code, your reference displays Obj-C instead. – LinusGeffarth Nov 13 '15 at 14:57
  • 1
    The link leads to Apple's documentation, where are all information, which could Jan possibly need, not only specific parts (methods/properties). Apple has the sample code only in ObjC in this case, but it could be easily translated to Swift. – David Rysanek Nov 14 '15 at 10:14
-1

2023

extension URL {
    static func generageEmailUrl(email: String, subject: String = "", body: String = "") -> URL {
        if let encodedParams = "subject=\(subject)&body=\(body)"
            .addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
            return URL(string: "mailto:\(email)?\(encodedParams)")!
        }
        
        return  URL(string: "mailto:\(email)")!
    }
}

usage in SwiftUI from iOS and macOS:

Link("Support Email", destination: URL.generageEmailUrl(email: "support@videq.com", subject: "VideQ feedback", body: "some body text") )
Andrew_STOP_RU_WAR_IN_UA
  • 9,318
  • 5
  • 65
  • 101