How to send an attachment in email using Swift(ios)?

Knowing how to send attachments in the email is very important since most of the application has sharing features. Hence having hands-on experience is important.
In this post, we will be seeing how to send an attachment in the mail using Swift.
So, let’s get started.
For this, we will be using MFMailComposeViewController, which is a standard view controller, whose interface lets the user manage, edit, and send email messages.
You can read more about it here https://developer.apple.com/documentation/messageui/mfmailcomposeviewcontroller
We will also be using MFMailComposeViewControllerDelegate to handle results from MFMailComposeResult.
You can read about it here https://developer.apple.com/documentation/messageui/mfmailcomposeviewcontrollerdelegate
We will be creating one sample application to understand,
Step 1 − Open Xcode → Single View Application → Name it EmailAttachment
Step 2 − Open Main.storyboard and add one button name it sends mail as shown below,
Step 3 − Create @IBAction and name it btnSendMail as below
@IBAction func btnSendMail(_ sender: Any) { }
Step 4 − In ViewController.swift, Import MessageUI
import MessageUI
Step 5 − Confirm the class to MFMailComposeViewControllerDelegate
class ViewController: UIViewController, MFMailComposeViewControllerDelegate
Step 6 − Add attachment file to project,
Step 7 − In btnSendMail write below function,
@IBAction func btnSendMail(_ sender: Any) {
   if MFMailComposeViewController.canSendMail() {
      let mail = MFMailComposeViewController()
      mail.setToRecipients(["test@gmail.com"])
      mail.setSubject("GREETING")
      mail.setMessageBody("Welcome to Tutorials Point!", isHTML: true)
      mail.mailComposeDelegate = self
      //add attachment
      if let filePath = Bundle.main.path(forResource: "sampleData", ofType: "json") {
         if let data = NSData(contentsOfFile: filePath) {
            mail.addAttachmentData(data as Data, mimeType: "application/json" , fileName: "sampleData.json")
         }
      }
      present(mail, animated: true)
      }
   else {
      print("Email cannot be sent")
   }
}
And you’re done!!
But we need to handle other conditions also, such as a message sent, canceled or failed. For this only we’ve conformed to the above protocol,
Let’s implement delegate methods,
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
   if let _ = error {
      self.dismiss(animated: true, completion: nil)
   }
   switch result {
      case .cancelled:
      print("Cancelled")
      break
      case .sent:
      print("Mail sent successfully")
      break
      case .failed:
      print("Sending mail failed")
      break
      default:
      break
   }
   controller.dismiss(animated: true, completion: nil)
}
And you’re done!!
Run the program in a real device,
Complete code
import UIKit
import MessageUI
class ViewController: UIViewController, MFMailComposeViewControllerDelegate {
   override func viewDidLoad() {
   }
   @IBAction func btnSendMail(_ sender: Any) {
      if MFMailComposeViewController.canSendMail() {
         let mail = MFMailComposeViewController()
         mail.setToRecipients(["test@gmail.com"])
         mail.setSubject("GREETING")
         mail.setMessageBody("Welcome to Tutorials Point!", isHTML: true)
         mail.mailComposeDelegate = self
         if let filePath = Bundle.main.path(forResource: "sampleData", ofType: "json") {
            if let data = NSData(contentsOfFile: filePath) {
               mail.addAttachmentData(data as Data, mimeType: "application/json" , fileName: "sampleData.json")
            }
         }
         present(mail, animated: true)
      }
      else {
         print("Email cannot be sent")
      }
   }
   func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result:          MFMailComposeResult, error: Error?) {
      if let _ = error {
         self.dismiss(animated: true, completion: nil)
      }
      switch result {
         case .cancelled:
         print("Cancelled")
         break
         case .sent:
         print("Mail sent successfully")
         break
         case .failed:
         print("Sending mail failed")
         break
         default:
         break
      }
      controller.dismiss(animated: true, completion: nil)
   }
}