Send mail with file attachment
Solution 1
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
And here is an image where I have enabled App Sandbox and allowed my app to read content in my Downloads
folder
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.
Solution 2
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)
}
}
Solution 3
First of all you should import import MessageUI
. For this add framework to the project.
Example:
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.
![Musyanon](https://i.stack.imgur.com/zYUz1.png?s=256&g=1)
Musyanon
Updated on June 27, 2022Comments
-
Musyanon about 2 years
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
-
Musyanon over 7 yearsThanks for you help ! Finaly I have understand why I can't import MessageUI, because it's only for IOS app. My Project is for Mac app. How can I do it for Mac app ?
-
Oleg Gordiichuk over 7 years@Musyanon you should ask another question. With proper question tags. Because in this way we going to corrupt this question.
-
Musyanon over 7 yearsI don't understand, my question is only for mac app. It's not same tags ? Sorry I'm newbie in xcode...
-
pbodsk over 7 years@Musyanon, I think what Oleg means is that you should add OSX/MacOS as a tag to your question (like you've added swift, xcode and so on already) so we can see that this is macOS and not iOS (as most questions here relates to iOS). I've added the tag for you :)
-
Musyanon over 7 yearsAwesome ! This code work perfectly ! Thank you very much :)
-
Mohsin Khubaib Ahmed over 5 years@pbodsk this is for MacOSX application right, and not for iOS Application?
-
pbodsk over 5 years@MohsinKhubaibAhmed I'm afraid so yes.
NSSharingService
is only available in AppKit it seems, and not in UIKit. -
Achyut Sagar over 3 years@pbodsk What if I want to generate a file programmatically and then send it?
-
pbodsk over 3 years@AchyutSagar its been a while since I wrote this so I'm not up to date here sorry :) But if I look at the blog post I linked to, it seems you need to have a file somewhere that you refer to. So that would mean that you first generate some content, then you convert it to Data so you can save it. Next you save it and then you should be good to go...I hope. Sorry, that's the best I can come up with, hope it helps you.