Email CSV using MFMailComposeViewController in swift - ios

I am using this code to export CSV file https://gist.github.com/kenechilearnscode/2d5d35f550f593332319
And it is exporting correctly but I want to email this CSV using MFMailComposeViewController. The above code opens an applicationActivities from where I can choose mail and the file is attached but the subject and recipients are not set. Code I am using to email the CSV is following. Its setting the subject and recipients etc but not attaching the CSV file.
if( MFMailComposeViewController.canSendMail() ) {
print("Can send email.")
let mailComposer = MFMailComposeViewController()
mailComposer.mailComposeDelegate = self
//Set the subject and message of the email
mailComposer.setSubject("Patient Data")
mailComposer.setMessageBody("Please find attached herewith complete patient data", isHTML: false)
mailComposer.setToRecipients(secondaryEmailList)
mailComposer.setCcRecipients([masterEmail])
if let filePath = Bundle.main.path(forResource: "export", ofType: "csv") {
print("File path loaded.")
if let fileData = NSData(contentsOfFile: filePath) {
print("File data loaded.")
mailComposer.addAttachmentData(fileData as Data, mimeType: "text/csv", fileName: "export")
}
}
self.present(mailComposer, animated: true, completion: nil)
}
Here is the code I am using to generate CSV file
func saveAndExport(exportString: String) {
let exportFilePath = NSTemporaryDirectory() + "export.csv"
let exportFileURL = NSURL(fileURLWithPath: exportFilePath)
FileManager.default.createFile(atPath: exportFilePath, contents: NSData() as Data, attributes: nil)
var fileHandleError: NSError? = nil
var fileHandle: FileHandle? = nil
do {
fileHandle = try FileHandle(forWritingTo: exportFileURL as URL)
} catch {
print("Error with fileHandle")
}
if fileHandle != nil {
fileHandle!.seekToEndOfFile()
let csvData = exportString.data(using: String.Encoding.utf8, allowLossyConversion: false)
fileHandle!.write(csvData!)
fileHandle!.closeFile()
let firstActivityItem = NSURL(fileURLWithPath: exportFilePath)
let activityViewController : UIActivityViewController = UIActivityViewController(
activityItems: [firstActivityItem], applicationActivities: nil)
activityViewController.excludedActivityTypes = [
UIActivityType.assignToContact,
UIActivityType.saveToCameraRoll,
UIActivityType.postToFlickr,
UIActivityType.postToVimeo,
UIActivityType.postToTencentWeibo
]
self.present(activityViewController, animated: true, completion: nil)
}
}

Related

Share Image Via URL

I am creating Images app from my WordPress website with json and i am using swift, i want to share image on Social Networks from my app , currently i tried this code it works but only with image name i want to share image from image url, is that possible ?
this is my code
let myWebsite = NSURL(string: "nice")
let img: UIImage = UIImage(named:"splash")!
guard let url = myWebsite else {
print("nothing found")
return
}
let shareItems:Array = [img,url]
let activityViewController:UIActivityViewController = UIActivityViewController(activityItems: shareItems, applicationActivities: nil)
activityViewController.excludedActivityTypes = [UIActivity.ActivityType.print, UIActivity.ActivityType.postToWeibo, UIActivity.ActivityType.copyToPasteboard, UIActivity.ActivityType.addToReadingList, UIActivity.ActivityType.postToVimeo]
self!.present(activityViewController, animated: true, completion: nil)
If you need to download an image and then share you should do that separately, there is no single method that does that for you. Here is how:
func shareImageFromUrl(_ string: String) {
guard let myUrl = URL(string: string) else {
print("Invalid url!")
return
}
URLSession.shared.dataTask(with: myUrl) { (data, _, _) in
guard let data = data,
let image = UIImage(data: data) else
{ return }
let activityViewController:UIActivityViewController = UIActivityViewController(activityItems: [image], applicationActivities: nil)
activityViewController.excludedActivityTypes = [UIActivity.ActivityType.print, UIActivity.ActivityType.postToWeibo, UIActivity.ActivityType.copyToPasteboard, UIActivity.ActivityType.addToReadingList, UIActivity.ActivityType.postToVimeo]
DispatchQueue.main.async {
self.present(activityViewController, animated: true, completion: nil)
}
}.resume()
}

share pdf file using UIActivityViewController in Swift 4

I am using UIActivityViewController to share a PDF file:
let pdfFilePath = URL(string: "https://www.tutorialspoint.com/swift/swift_tutorial.pdf")
let pdfData = NSData(contentsOf: pdfFilePath!)
let activityVC = UIActivityViewController(activityItems: [pdfData!], applicationActivities: nil)
present(activityVC, animated: true, completion: nil)
The below result is displayed:
What I want is to display more features like "copy to Books" and "Add to Notes" like the following:
If you want to share your pdf file which is on the server and you have a URL. Then first you download that file in your device and then share that file to any other person.
If you using Alamofire in your code then there is code.
Stape 1
import Alamofire
Stape 2
Add this function in your class:-
func downloadPdf(downloadUrl : String, fileName: String, completionHandler:#escaping(String, Bool)->()){
let destinationPath: DownloadRequest.DownloadFileDestination = { _, _ in
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0];
let fileURL = documentsURL.appendingPathComponent("\(fileName).pdf")
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
print(downloadUrl)
Alamofire.download(downloadUrl, to: destinationPath)
.downloadProgress { progress in
}
.responseData { response in
print("response: \(response)")
switch response.result{
case .success:
if response.destinationURL != nil, let filePath = response.destinationURL?.absoluteString {
completionHandler(filePath, true)
}
break
case .failure:
completionHandler("", false)
break
}
}
}
Stape 3
Add this action on your share button
#IBAction func btnShareAction(_ sender: UIButton) {
let myURL = "http://www.demo.com/demo.pdf" // change this with your URL
self.downloadPdf(downloadUrl : myURL, fileName: "invoice") { (localFileUrl, bool) in
let fileURL = NSURL(fileURLWithPath: localFileUrl)
let activityViewController = UIActivityViewController(activityItems: [fileURL], applicationActivities: nil)
self.present(activityViewController, animated: true, completion: nil)
}
}
Simple Steps! Copy paste the give code
#objc private func btnShareTapped(_ sender: UIButton) {
guard let urlString = strURL,
let url = URL(string: urlString),
let docPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last else {
return
}
let actualPath = docPath.appendingPathComponent("Statement.pdf")
let pdfData = try? Data.init(contentsOf: url)
do {
try pdfData?.write(to: actualPath, options: .atomic)
let fileURL = URL(fileURLWithPath: actualPath.absoluteString)
let activityVC = UIActivityViewController(activityItems: [fileURL],
applicationActivities: nil)
present(activityVC, animated: true)
} catch {
debugPrint("Pdf could not be saved")
}
}

How can I share location from my app to WhatsApp in Swift 3

I'm trying to share a location from my iOS app to WhatsApp and I want it to look like this:
What I'm doing is sending vCard with this code :
func vCardURL(from coordinate: CLLocationCoordinate2D, with name: String?) -> URL {
let vCardFileURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("Shared Location.loc.vcf")
let vCardString = [
"BEGIN:VCARD",
"VERSION:3.0",
//"PRODID:-//Apple Inc.//iPhone OS 10.3.2//EN",
"N:;My Location;;;",
"FN:My Location",
"item1.URL;type=pref:https://maps.apple.com/?ll=50.359890\\,12.934560&q=My%20Location&t=m",
"item1.X-ABLabel:map url",
"END:VCARD"
].joined(separator: "\n")
do {
try vCardString.write(toFile: vCardFileURL.path, atomically: true, encoding: .utf8)
} catch let error {
print("Error, \(error.localizedDescription), saving vCard: \(vCardString) to file path: \(vCardFileURL.path).")
}
print(vCardString)
return vCardFileURL
} // end of function
// calling the methood above
let vURL = LocationVCard.vCardURL(from: self.newLocation.coordinate, with: "Berlin")
let activityViewController = UIActivityViewController(activityItems: [vURL], applicationActivities: nil)
self.present(activityViewController, animated: true, completion: nil)
But I always end up with this style instead of what I want:
No need to save the vCard string to a file, just convert it to Data and wrap it with NSItemProvider with the correct type identifier public.vcard, and it'll work just fine:
let data = vCardString.data(using: .utf8)! as NSData
let item = NSItemProvider(item: data, typeIdentifier: "public.vcard")
let activityViewController = UIActivityViewController(activityItems: [item], applicationActivities: nil)

Using UIActivityViewController to specify file type

Following up from this question, how would I go about using UIActivityViewController to specify the file type of a file I am sharing over airdrop?
Worked it out:
let myFileManager = FileManager.default
var activityArray = [NSURL]()
activityArray.removeAll()
for (i, data) in dataToShare.enumerated() {
let docsurl = try! myFileManager.url(for:.documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let myurl = docsurl.appendingPathComponent("shareData\(i).gymProf")
var myUrlString = myurl.absoluteString
myUrlString = myUrlString.replacingOccurrences(of: "file://", with: "")
myFileManager.createFile(atPath: myUrlString, contents: data, attributes: nil)
activityArray.append(NSURL(fileURLWithPath: myUrlString))
if myFileManager.fileExists(atPath: myUrlString) {
print("File Exists at \(myUrlString)")
} else {
print("File not found")
}
}
let activityViewController = UIActivityViewController(activityItems: activityArray, applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
self.present(activityViewController, animated: true, completion: nil)

Sharing csv file through UIActivityViewController

I'm trying to share a csv file using UIActivityViewController.
I want to share both through email and other applications, like Telegram.
Through Telegram the file gets shared correctly, but using email, the email has no attachments.
Also, the csv file has no extension, should I set a MIME type? How?
#IBAction func shareSheet(sender: AnyObject) {
let firstActivityItem = "Hi, here is the csv file"
//do i really need this? what for?
let secondActivityItem : NSURL = NSURL(string: "http//:urlyouwant")!
let csv : NSData! = NSData(contentsOfFile: NSTemporaryDirectory() + "export.csv")
let activityViewController : UIActivityViewController = UIActivityViewController(
activityItems: [firstActivityItem, secondActivityItem, csv], applicationActivities: nil)
//set the email title
activityViewController.setValue(firstAcxtivityItem, forKey: "subject")
self.presentViewController(activityViewController, animated: true, completion: nil)
}
This is the code I use to send a CSV via the mail composer
let csvString = "Your CSV String"
let subject = "Subject of your email"
let fileName = "CSV Filename.csv"
let composeVC = MFMailComposeViewController()
composeVC.mailComposeDelegate = self
composeVC.setSubject(subject)
if let csvData = csvString.data(using: String.Encoding.utf8) {
composeVC.addAttachmentData(csvData, mimeType: "text/csv", fileName: fileName)
}
self.present(composeVC, animated: true, completion: nil)

Resources