Swift pdf attachment in Mail - swift

In my code
class DocViewController: UIViewController,UITextViewDelegate, MFMailComposeViewControllerDelegate{
var result:String!
override func viewDidLoad() {
super.viewDidLoad()
result = "/Test - " + dateToday!
func getPDFFileName(_ name: String) -> String {
let newPDFName = "\(name).pdf"
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = paths[0]
let pdfFileName: String = (documentsDirectory as String).appending(newPDFName);
print(pdfFileName)
return pdfFileName
}
#IBAction func sendMail(_ sender: UIBarButtonItem) {
let mailComposeViewController = configuredMailComposeViewController()
if MFMailComposeViewController.canSendMail() {
self.present(mailComposeViewController, animated: true, completion: nil)
} else {
self.showSendMailErrorAlert()
}
}
func configuredMailComposeViewController() -> MFMailComposeViewController {
let mailComposer:MFMailComposeViewController = MFMailComposeViewController()
mailComposer.mailComposeDelegate = self
let recipients = ["a#a.com"]
//Set the subject and message of the email
mailComposer.setToRecipients(recipients)
mailComposer.setSubject("Test")
mailComposer.setMessageBody("Send Saved PDF File", isHTML: false)
if let filePath = Bundle.main.path(forResource: getPDFFileName(result), ofType: "pdf") {
print("File path loaded.")
if let fileData = NSData(contentsOfFile: filePath) {
print("File data loaded.")
mailComposer.addAttachmentData(fileData as Data, mimeType: "application/pdf", fileName: "pdf")
}
present(mailComposer, animated: true, completion: nil)
}
return mailComposer
}
I am creating pdf and would like to send through mail. Mail works. But the pdf is not attached. If I use simulator the directory is /Users/xxxxxx/Library/Developer/CoreSimulator/Devices/91BD76E3-7BD6-49E9-87E7-63C87BE980EF/data/Containers/Data/Application/16350B51-6898-45AA-BEF3-F0B0E4FF7556/Documents/Test - Monday, 25 December 2017.pdf
if I use iPhone, the save directory is:
/var/mobile/Containers/Data/Application/7374E0A1-3E49-494D-B554-1D9C761FC7C1/Documents/Test - Monday, 25 December 2017.pdf and the console message is 2017-12-25 20:36:45.344149+0530 Karma[7690:1157301] [App] if we're in the real pre-commit handler we can't actually add any new fences due to CA restriction when I try to attach mail. Where am I doing wrong? How to specify the same location for the iPhone to attache the created pdf file? Please help.
EDIT:
Below code works and attaching the created pdf with mail:
class DocViewController: UIViewController,UITextViewDelegate, MFMailComposeViewControllerDelegate{
var result:String!
override func viewDidLoad() {
super.viewDidLoad()
result = "/Test - " + dateToday!
func getPDFFileName(_ name: String) -> String {
let newPDFName = "\(name).pdf"
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)[0] as! String
let pdfFileName: String = (documentsDirectory as String).appending(newPDFName);
print(pdfFileName)
return pdfFileName
}
#IBAction func sendMail(_ sender: UIBarButtonItem) {
let mailComposeViewController = configuredMailComposeViewController()
if MFMailComposeViewController.canSendMail() {
present(mailComposeViewController, animated: true, completion: nil)
} else {
self.showSendMailErrorAlert()
}
}
func configuredMailComposeViewController() -> MFMailComposeViewController {
let mailComposer:MFMailComposeViewController = MFMailComposeViewController()
mailComposer.mailComposeDelegate = self
let recipients = ["a#a.com"]
//Set the subject and message of the email
mailComposer.setToRecipients(recipients)
mailComposer.setSubject("Test")
mailComposer.setMessageBody("Send Saved PDF File", isHTML: false)
let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)[0] as! String
let filePath = getPDFFileName(result)
print("File path loaded.")
if let fileData = NSData(contentsOfFile: filePath) {
print("File data loaded.")
mailComposer.addAttachmentData(fileData as Data, mimeType: "application/pdf", fileName: result)
self.present(mailComposer, animated: true, completion: nil)
}
return mailComposer
}
}

Swift 4.0
try this
let mailComposer = MFMailComposeViewController()
mailComposer.mailComposeDelegate = self
//Set to recipients
mailComposer.setToRecipients(["your email address heres"])
//Set the subject
mailComposer.setSubject("email with document pdf")
//set mail body
mailComposer.setMessageBody("This is what they sound like.", isHTML: true)
if let filePath = Bundle.main.path(forResource: "All_about_tax", ofType: "pdf")
{
print("File path loaded.")
if let fileData = NSData(contentsOfFile: filePath)
{
print("File data loaded.")
mailComposer.addAttachmentData(fileData, mimeType: "application/pdf", fileName: "All_about_tax.pdf")
}
}
//this will compose and present mail to user
self.present(mailComposer, animated: true, completion: nil)

Related

Share pdf on web view to another devices using swift code

I have a WKWebView which displayed pdf. I want to share the file to another devices such as iPad, iPhone.... using the share button. I tried to display the pdf in preview so it will have the iOS share button the code below.
import UIKit
import WebKit
class ShowPDFView: UIViewController, UIDocumentInteractionControllerDelegate {
#IBAction func SharePDFFile(_ sender: Any) {
let fileName = "testPDF"
guard let urlPath = Bundle.main.url(forResource: fileName, withExtension: "pdf") else {return}
let controller = UIDocumentInteractionController(url: urlPath)
controller.delegate = self
controller.presentPreview(animated: true)
}
func documentInteractionControllerViewControllerForPreview(controller: UIDocumentInteractionController!) -> UIViewController! {
return self
}
func documentInteractionControllerViewForPreview(controller: UIDocumentInteractionController!) -> UIView! {
return self.view
}
func documentInteractionControllerRectForPreview(controller: UIDocumentInteractionController!) -> CGRect{
return self.view.frame
}
I got runtime error.
[MC] Reading from private effective user settings.
The preview does not loaded. Does anyone know why?
This function works for me. In Swift 4
#IBAction func SharePDFFile(_ sender: Any) {
let fm = FileManager.default
var pdfURL = (fm.urls(for: .documentDirectory, in: .userDomainMask)).last! as URL
pdfURL = pdfURL.appendingPathComponent("johnMilky.pdf") as URL
//Rename document name to "myFile.pdf"
let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("johnMilkyFile.pdf") as NSURL
do {
let data = try Data(contentsOf: pdfURL)
try data.write(to: url as URL)
let activitycontroller = UIActivityViewController(activityItems: [url], applicationActivities: nil)
if activitycontroller.responds(to: #selector(getter: activitycontroller.completionWithItemsHandler))
{
activitycontroller.completionWithItemsHandler = {(type, isCompleted, items, error) in
if isCompleted
{
print("completed")
}
}
}
//activitycontroller.excludedActivityTypes = [UIActivity.ActivityType.airDrop]
activitycontroller.popoverPresentationController?.sourceView = self.view
self.present(activitycontroller, animated: true, completion: nil)
}
catch {
print(error)
}
}

Swift : Trouble Exporting Database

I'm trying to Export my Database.
I've tried by Email and by sharing it.
The thing is that I want to export the current state of the dataBase (with all the information in it).
I've tried this code :
func exportDatabase(){
var url:String = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last! as String
url = url + "/WalletDatabase.sqlite"
let fileManager = FileManager.default
if fileManager.fileExists(atPath: url) {
sendMail(sUrl: url)
}else{
print("error")
}
}
func sendMail(sUrl:String){
if( MFMailComposeViewController.canSendMail() ) {
print("Can send email.")
let fileManager = FileManager.default
let mailComposer = MFMailComposeViewController()
mailComposer.setToRecipients(["***#gmail.com"])
mailComposer.mailComposeDelegate = self
//Set the subject and message of the email
mailComposer.setSubject("Lorem Ipsum")
mailComposer.setMessageBody("Lorem Ipsum.", isHTML: false)
if let fileData = NSData(contentsOfFile: sUrl) {
print("File data loaded.")
mailComposer.addAttachmentData(fileData as Data, mimeType: "application/x-sqlite3", fileName: "WalletDatabase")
}
let fileData = fileManager.contents(atPath: sUrl)
} else {
print("error")
}
But :
The file send doesn't have any type
The database is empty, only the table and col remain
Could you guys give me a little help
I fix it by adding this following code :
static func migrateStoreSwift() -> NSURL
{
let lApp:AppController = UIApplication.shared.delegate as! AppController;
let lCurrentStore:NSPersistentStore = lApp.persistentStoreCoordinator.persistentStores.last!
let lNewDataBase = "Database.sqlite"
let lNewStoreURL:NSURL = lApp.applicationDocumentsDirectory()?.appendingPathComponent(lNewDataBase) as! NSURL
try! lApp.persistentStoreCoordinator.migratePersistentStore(lCurrentStore, to: lNewStoreURL as URL, options: nil, withType: NSSQLiteStoreType)
return lNewStoreURL
}
This code create a copy of the current version of the database.

mailComposeViewController with pdf in PdfKit swift

I have this code for one the pdf file in Swift with PdfKit
but the the email don't open the in app I d'ont received any error
let mailComposeViewController = MFMailComposeViewController()
if let lastPathComponent = pdfDocument?.documentURL?.lastPathComponent,
let documentAttributes = pdfDocument?.documentAttributes,
let attachmentData = pdfDocument?.dataRepresentation() {
if let title = documentAttributes["Title"] as? String {
mailComposeViewController.setSubject(title)
}
mailComposeViewController.addAttachmentData(attachmentData, mimeType: "application/pdf", fileName: lastPathComponent)
}
var paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
var documentsDirectory: String = paths[0]
var finalPath: String = URL(fileURLWithPath: documentsDirectory).appendingPathComponent("myPdf.pdf").absoluteString
print("\(finalPath)")
var error: Error? = nil
var myData = Data(base64Encoded: pdfContent, options: [])
var url = URL.fileURL(withPath: finalPath)
if error != nil {
print("Fail: \(error?.localizedDescription)")
}
var mailComposer = MFMailComposeViewController()
if MFMailComposeViewController.canSendMail() {
mailComposer.mailComposeDelegate = self
mailComposer.addAttachmentData(myData!, mimeType: "application/pdf", fileName: "myPdf.pdf")
self.present(mailComposer, animated: true, completion: nil)
}

Swift3 file preview not working

I think something changed within Swift that disabled me from previewing my files. It worked fine previously. If I click on say a PDF file in my app, I see the title of the PDF, but the content of PDF (preview) area does not show.
Below is my code & logs & also the screenshot. If anyone has an idea of where I can fix the issue, any help would be greatly appreciated.
// When file is clicked this method is called
#objc private func handleTapped() {
guard let url = self.file.fileUrl else { return }
if self.file.isDownloaded {
self.showDocumentController(url: self.file.urlInDocumentsDirectory! as NSURL)
return
}
SVProgressHUD.showProgress(0)
let destination: DownloadRequest.DownloadFileDestination = { _, _ in
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileURL = documentsURL.appendingPathComponent("pig.png")
return (documentsURL, [.removePreviousFile, .createIntermediateDirectories])
}
Alamofire.download(url, to: destination)
.downloadProgress { (download) in
DispatchQueue.main.async() {
SVProgressHUD.showProgress(Float(download.fractionCompleted))
}
}.validate(statusCode: 200..<300)
.response { (response) in
SVProgressHUD.dismiss()
guard response.response?.statusCode == 200 else { return }
let directoryURL = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let pathURL = URL(fileURLWithPath: directoryURL, isDirectory: true)
//pathURL: file:///var/mobile/Containers/Data/Application/6DDCCC30-107C-4613-B63D-18962C3D06D3/Documents/
guard let fileName = response.response?.suggestedFilename else { return }
//fileName: 05_기조강연_RobertMankin_BETTER+OFFICES+GREATER+INNOVATION.pdf
let fileURL = pathURL.appendingPathComponent(fileName)
//fileURL: file:///var/mobile/Containers/Data/Application/6DDCCC30-107C-4613-B63D-18962C3D06D3/Documents/05_%E1%84%80%E1%85%B5%E1%84%8C%E1%85%A9%E1%84%80%E1%85%A1%E1%86%BC%E1%84%8B%E1%85%A7%E1%86%AB_RobertMankin_BETTER+OFFICES+GREATER+INNOVATION.pdf
self.saveFileURL(url: fileURL as NSURL)
self.showDocumentController(url: fileURL as NSURL)
}
}
private func saveFileURL(url: NSURL) {
self.file.urlInDocumentsDirectory = url as URL
let realm = RealmService.defaultRealm
try! realm?.write {
realm?.add(self.file, update: true)
}
self.file = self.file.copyFromRealm()
}
private func showDocumentController(url: NSURL) {
let docController = UIDocumentInteractionController(url: url as URL)
docController.delegate = self
docController.presentPreview(animated: true)
}
// MARK: UIDocumentInteractionControllerDelegate methods
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
if let controller = UIApplication.shared.keyWindow?.topMostViewController() {
return controller
}
return UIViewController()
}
this is how the preview shows
Here Is The Code
import UIKit
import Alamofire
class ViewController: UIViewController, UIWebViewDelegate
{
#IBOutlet weak var WebView: UIWebView!
var NewsURL: String = ""
override func viewDidLoad()
{
super.viewDidLoad()
Self.LoadPdf()
}
func LoadPdf()
{
let url = NSURL (string: "\(http://)") //Your Pdf URL Here
let requestObj = NSURLRequest(URL: url!);
WebView.loadRequest(requestObj)
}
}

open PDF URL in iOS 8?

I have write this code to show pdf using UIDocumentInteractionController.But,I don't know how to search pdf at local directory and open in iOS 8 and below..Any help?
let filename = history.invoiceLongDate // 01223642
if !filename.isEmpty{
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let docs = paths[0]
let pathURL = NSURL(fileURLWithPath: docs, isDirectory: true)
if #available(iOS 9.0, *) {
let fileURL = NSURL(fileURLWithPath: "\(filename)_my_invoice.pdf", isDirectory: false, relativeToURL: pathURL)
self.docController = UIDocumentInteractionController(URL: fileURL)
self.docController?.delegate = self
self.docController?.presentOptionsMenuFromRect(sender.frame, inView: self.view, animated: true)
} else {
// Fallback on earlier versions
// Any Help with that?
}
}
You can view PDF in iOS 8 by using webview. Try below code,
if let pdf = NSBundle.mainBundle().URLForResource("myPDF", withExtension: "pdf", subdirectory: nil, localization: nil) {
let req = NSURLRequest(URL: pdf)
let webView = UIWebView(frame: CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height))
webView.loadRequest(req)
self.view.addSubview(webView)
}
OR
if let baseUrl = NSURL.fileURLWithPath(pathURL) {
let fileURL = baseUrl.URLByAppendingPathComponent(NFConstants.NFCoreDataStringIdentifiers.CoreDataStoresPathComponent.rawValue)
}
Hope this will be helpful to you.
UIDocumentInteractionController is available with (iOS 3.2, *).
For Viewing PDF file:
var documentInteractionController: UIDocumentInteractionController!
#IBAction func openDocument(sender: UIButton) {
let URL: NSURL = NSBundle.mainBundle().URLForResource("pdf-sample", withExtension: "pdf")!
if (URL != "") {
// Initialize Document Interaction Controller
self.documentInteractionController = UIDocumentInteractionController(URL: URL)
// Configure Document Interaction Controller
self.documentInteractionController.delegate = self
// Present Open In Menu
self.documentInteractionController.presentOptionsMenuFromRect(sender.frame, inView: self.view, animated: true)
//presentOpenInMenuFromRect(button.frame, inView: self.view, animated: true)
}
}
// MARK: UIDocumentInteractionControllerDelegate
func documentInteractionControllerViewControllerForPreview(controller: UIDocumentInteractionController) -> UIViewController {
return self
}