Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send mail with file attachment

I search solution to send a mail with attachment. I have this code but the file is not attached...

if let url = URL(string: "mailto:\(email)?subject=report&body=see_attachment&attachment=/Users/myname/Desktop/report.txt") {
    NSWorkspace.shared().open(url)
}

I have see it maybe work with MessageUI, but I can't import this framework I don't know why. I get this error message : No such module 'MessageUI' I checked in General > Linked Frameworks and Libraries, but there are not MessageUI...

Anyone have a solution to add file in mail? Thanks

like image 374
Musyanon Avatar asked Mar 10 '17 09:03

Musyanon


3 Answers

It seems that attachment in mailto: URLs are not supported on macOS (not always at least...details seems sketchy dependent on where you look on the internet :))

What you can use instead I found out from this blog post, is an instance of NSSharingService documented here

Here is an example demonstrating how to use it.

And in your case you could do something like:

let email = "your email here"
let path = "/Users/myname/Desktop/report.txt"
let fileURL = URL(fileURLWithPath: path)

let sharingService = NSSharingService(named: NSSharingServiceNameComposeEmail)
sharingService?.recipients = [email] //could be more than one
sharingService?.subject = "subject"
let items: [Any] = ["see attachment", fileURL] //the interesting part, here you add body text as well as URL for the document you'd like to share

sharingService?.perform(withItems: items)

Update

So @Spire mentioned in a comment below that this won't attach a file.

It seems there is a gotcha to be aware of.

For this to work you need to look into your App Capabilities.

You can either:

  • disable App Sandbox
  • enable read access for the folders from where you would like to fetch content.

I've attached a couple of screenshots.

Here is how this looks if I have disabled App Sandbox under Capabilities

App Sandbox disabled

And here is an image where I have enabled App Sandbox and allowed my app to read content in my Downloads folder

App Sandbox enabled

If I do the above, I can access my file called document.txt, located in my Downloads folder, using this URL

let path = "/Users/thatsme/Downloads/document.txt"
let fileURL = URL(fileURLWithPath: path)

And attach that to a mail

Hope that helps you.

like image 106
pbodsk Avatar answered Oct 22 '22 02:10

pbodsk


import MessageUI
class ViewController: UIViewController,MFMailComposeViewControllerDelegate {

func sendMail() {
  if( MFMailComposeViewController.canSendMail()){
        print("Can send email.")

        let mailComposer = MFMailComposeViewController()
        mailComposer.mailComposeDelegate = self

        //Set to recipients
        mailComposer.setToRecipients(["[email protected]"])

        //Set the subject
        mailComposer.setSubject("email with document pdf")

        //set mail body
        mailComposer.setMessageBody("This is what they sound like.", isHTML: true)
        let pathPDF = "\(NSTemporaryDirectory())contract.pdf"
            if let fileData = NSData(contentsOfFile: pathPDF) 
            {
                print("File data loaded.")
                mailComposer.addAttachmentData(fileData as Data, mimeType: "application/pdf", fileName: "contract.pdf")
            }

        //this will compose and present mail to user
        self.present(mailComposer, animated: true, completion: nil)
    }
    else
    {
        print("email is not supported")
    }

  func mailComposeController(_ didFinishWithcontroller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?)
  {
    self.dismiss(animated: true, completion: nil)
  }
}
like image 30
Yakup Ad Avatar answered Oct 22 '22 00:10

Yakup Ad


First of all you should import import MessageUI. For this add framework to the project.

Example:

enter image description here

After investigate MFMailComposeViewControllerDelegate for knowing when you end sending email.

Example of the creating of the email:

if( MFMailComposeViewController.canSendMail() ) {
        println("Can send email.")

        let mailComposer = MFMailComposeViewController()
        mailComposer.mailComposeDelegate = self

        //Set the subject and message of the email
        mailComposer.setSubject("Have you heard a swift?")
        mailComposer.setMessageBody("This is what they sound like.", isHTML: false)

        if let filePath = NSBundle.mainBundle().pathForResource("swifts", ofType: "wav") {
            println("File path loaded.")

            if let fileData = NSData(contentsOfFile: filePath) {
                println("File data loaded.")
                mailComposer.addAttachmentData(fileData, mimeType: "audio/wav", fileName: "swifts")
            }
        }
        self.presentViewController(mailComposer, animated: true, completion: nil)
    }

Working example is presented by this link.

like image 2
Oleg Gordiichuk Avatar answered Oct 22 '22 00:10

Oleg Gordiichuk