I've created a streaming video app that also downloads videos locally. How can I display downloaded videos in the iPhone/iPad Storage sections of settings?
I'm downloading using background tasks, and on complete running
let docsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let destinationUrl = docsUrl.appendingPathComponent(videoId + ".mp4")
let fileManager = FileManager.default
try? fileManager.removeItem(at: destinationUrl)
do {
try fileManager.copyItem(at: location, to: destinationUrl)
} catch let error {
print("Could not copy file to disk: \(error.localizedDescription)")
return
}
Apps like Netflix, Disney+ and Prime Video all show the downloaded shows and allow them to be deleted individually, but I haven't been able to figure out how it's done. All searches usually lead to guides for users on how to delete videos.
Anybody have any tips?
This code is working for me:
func downloadVideo1(videoString :String)
{
let myStringArr = videoString.components(separatedBy: "/")
let finalString = myStringArr[myStringArr.count - 1]
let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main)
let docsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let destinationUrl = docsUrl.appendingPathComponent(finalString)
if(FileManager().fileExists(atPath: destinationUrl.path)){
print("\n\nfile already exists\n\n")
}
else{
// setupProgress()
//DispatchQueue.global(qos: .background).async {
var request = URLRequest(url: URL(string: videoString)!)
request.httpMethod = "GET"
_ = session.dataTask(with: request, completionHandler: { (data, response, error) in
if(error != nil){
print("\n\nsome error occured\n\n")
return
}
if let response = response as? HTTPURLResponse{
if response.statusCode == 200{
DispatchQueue.main.async {
if let data = data{
if let _ = try? data.write(to: destinationUrl, options: Data.WritingOptions.atomic){
print("\n\nurl data written\n\n")
print(destinationUrl)
self.checkCount = self.checkCount + 1
if self.checkCount == self.availableMediaCount
{
self.progressView.isHidden = true
let vc = TeacherLessonPlanSB.instantiateViewController(withIdentifier: "DownloadLessonVC") as! DownloadLessonViewController
self.navigationController?.pushViewController(vc, animated: true)
}
}
else{
print("\n\nerror again\n\n")
}
}//end if let data
}//end dispatch main
}//end if let response.status
}
}).resume()
}
}
Related
I am getting getting multiple PDF urls from server response and showing them in tableview with download option for each cell.
I am able to download each pdf file only once, But, Tried to second time download, It is showing already downloaded error.
How to fix this?
Here is my code
func downloadButtonTapped(index: Int) {
let finalUrlStr = "(dataResponse?[index].brochure)")
let fileURL = URL(string: finalUrlStr)
let fileName = String((fileURL!.lastPathComponent)) as NSString
// Create destination URL
let documentsUrl:URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let destinationFileUrl = documentsUrl.appendingPathComponent("\(fileName)")
//Create URL to the source file you want to download
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url:fileURL!)
LoadingView.show()
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully downloaded. Status code: \(statusCode)")
}
do {
try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
do {
//Show UIActivityViewController to save the downloaded file
let contents = try FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
for indexx in 0..<contents.count {
if contents[indexx].lastPathComponent == destinationFileUrl.lastPathComponent {
let activityViewController = UIActivityViewController(activityItems: [contents[indexx]], applicationActivities: nil)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
self.present(activityViewController, animated: true, completion: nil)
LoadingView.hide()
}
}
}
}
catch (let err) {
// DispatchQueue.main.async {
print("error: \(err.localizedDescription)")
LoadingView.hide()
self.showBasicAlert(title: "\(err.localizedDescription)", message: "")
// }
}
} catch (let writeError) {
print("Error creating a file \(destinationFileUrl) : \(writeError)")
LoadingView.hide()
self.showBasicAlert(title: "\(writeError.localizedDescription)", message: "")
}
} else {
print("Error took place while downloading a file. Error description: \(error?.localizedDescription ?? "")")
self.showBasicAlert(title: "\(error?.localizedDescription ?? "")", message: "")
}
}
task.resume()
}
Even though, PDF not downloaded even one time before download file, activitycontroller displaying and If we close that without download/save file, Again trying to download, Same error message showing like already exist file
How to download multiple times like whenever user taps on download option, It should download the pdf file.
Also after downloaded pdf, I need to show open pdf from external not inside app
Any suggestions?
I have fixed it by myself by removing condition.
Now I am able to download whenever user tap on download button.
Here is the code.
func downloadButtonTapped(index: Int) {
// print("index \(index)")
let finalUrlStr = "(dataResponse?[index].brochure)")
let fileURL = URL(string: finalUrlStr)
if let fileUrl = fileURL {
let fileName = String((fileUrl.lastPathComponent)) as NSString
// Create destination URL
let documentsUrl:URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let destinationFileUrl = documentsUrl.appendingPathComponent("\(fileName)")
//Create URL to the source file you want to download
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url:fileUrl)
LoadingView.show()
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully downloaded. Status code: \(statusCode)")
}
do {
//Show UIActivityViewController to save the downloaded file
let contents = try FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
for indexx in 0..<contents.count {
if contents[indexx].lastPathComponent == destinationFileUrl.lastPathComponent {
let activityViewController = UIActivityViewController(activityItems: [contents[indexx]], applicationActivities: nil)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
self.present(activityViewController, animated: true, completion: nil)
LoadingView.hide()
}
}
}
}
catch (let err) {
print("error: \(err.localizedDescription)")
DispatchQueue.main.async {
LoadingView.hide()
self.showBasicAlert(title: "\(err.localizedDescription)", message: "")
}
}
}
}
task.resume()
}
}
Code:
let folderName = "coinFolder"
let fileManager = FileManager.default
let documentsFolder = try! fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let folderURL = documentsFolder.appendingPathComponent(folderName)
let folderExists = (try? folderURL.checkResourceIsReachable()) ?? false
do {
if !folderExists {
try! fileManager.createDirectory(at: folderURL, withIntermediateDirectories: false)
}
let destinationFileUrl = folderURL.appendingPathComponent("test23.pdf")
// let hello = Data("hello".utf8)
// try hello.write(to: fileURL)
let urlString = ""
let url = URL(string: urlString)
let fileName = String((url!.lastPathComponent)) as NSString
// Create destination URL
/* let documentsUrl:URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!
let destinationFileUrl = documentsUrl.appendingPathComponent("\(fileName)")*/
//Create URL to the source file you want to download
let fileURL = URL(string: urlString)
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url:fileURL!)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully downloaded. Status code: \(statusCode)")
}
do {
try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
do {
//Show UIActivityViewController to save the downloaded file
let contents = try FileManager.default.contentsOfDirectory(at: documentsFolder, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
for indexx in 0..<contents.count {
if contents[indexx].lastPathComponent == destinationFileUrl.lastPathComponent {
let activityViewController = UIActivityViewController(activityItems: [contents[indexx]], applicationActivities: nil)
self.present(activityViewController, animated: true, completion: nil)
}
}
}
catch (let err) {
print("error: \(err)")
}
} catch (let writeError) {
print("Error creating a file \(destinationFileUrl) : \(writeError)")
}
} else {
print("Error took place while downloading a file. Error description: \(error?.localizedDescription ?? "")")
}
}
task.resume()
}
i am working on sample a project to download PDF file and create folder inside files app and store pdf file inside it.above code is what tried to achieve same.but it is not working for me.is it possible do so?if so what is wrong with my code. any help will be appricated.thanks in advance
I assume you need to change from create:false to create:true
Change from
let documentsFolder = try! fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
To
let documentsFolder = try! fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
I'm trying to download a file from a server, by sending the id of the file. I tried several things but the file is getting downloaded as CFNetworkDownload.tmp file.
I want it to save as the file that exists. The file type can be PNG,JPEG,PDF,DOCX,PPTX,XLSX. Tried many things but in vain. I'm sure it must be something simple i'm missing to understand here
Tried the below. Difference being in most of the examples, the file name is in the URL. But I send id and get file in response.
How to download file in swift?
How To Download Multiple Files Sequentially using NSURLSession downloadTask in Swift
Below is my code.
func downloadFile(id : String, fileName : String) -> Void {
let session = URLSession.shared
let url = URL(string: qaDownloadURL+id)!
var request = URLRequest(url: url)
request.httpMethod = "POST"
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Success: \(statusCode)")
}
do {
// let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
//
// self.savePath = documentsUrl!.absoluteString + "/" + fileName
//
// let fileURL = URL(fileURLWithPath: self.savePath)
//
// let dataFromURL = NSData(contentsOf: tempLocalUrl)
// dataFromURL?.write(to: fileURL, atomically: true)
var documentsDirectory: String?
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
if paths.count > 0
{
documentsDirectory = paths.first!
}
self.savePath = documentsDirectory!// + "/" + fileName
let fileURL = URL(fileURLWithPath: self.savePath)
let dataFromURL = NSData(contentsOf: tempLocalUrl)
dataFromURL?.write(to: fileURL, atomically: true)
// try FileManager.default.copyItem(at: tempLocalUrl, to: fileURL)
DispatchQueue.main.async {
let documentController = UIDocumentInteractionController.init(url: fileURL)
documentController.delegate = self
documentController.presentPreview(animated: true)
}
} catch (let writeError) {
print("error writing file \(self.savePath) : \(writeError)")
}
} else {
print("Failure: %#", error?.localizedDescription);
}
}
task.resume()
}
You cannot write data into a location which represents a directory, you need to specify the full path including the file name.
Using modern URL related API you can replace the entire do block with
do {
let documentFolderURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let fileURL = documentFolderURL.appendingPathComponent(fileName)
try FileManager.default.copyItem(at: tempLocalUrl, to: fileURL)
DispatchQueue.main.async {
let documentController = UIDocumentInteractionController.init(url: fileURL)
documentController.delegate = self
documentController.presentPreview(animated: true)
}
}
or use URLSessionDataTask which returns the raw data rather than downloading the file to a temporary location and save the Data directly for example
let task = session.dataTask(with: request) { (data, response, error) in
guard error == nil else {
print(error!)
return
}
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Success: \(statusCode)")
}
do {
let documentFolderURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let fileURL = documentFolderURL.appendingPathComponent(fileName)
try data!.write(to: fileURL)
DispatchQueue.main.async {
let documentController = UIDocumentInteractionController.init(url: fileURL)
documentController.delegate = self
documentController.presentPreview(animated: true)
}
} catch {
print("error writing file \(fileName) : \(error)")
}
}
task.resume()
If this does not work the error is related to somewhere else.
I know how to get a remote URL in Swift
let remoteURL = NSURL(string: "https://myserver/file.txt")!
I know how to get a local URL in Swift
let localURL = NSURL(fileURLWithPath: documentsFolder + "/my_local_file.txt")
and unfortunately this does not work
NSFileManager.defaultManager().copyItemAtURL(remoteURL, toURL: localURL)
with the following error
The file “file.txt” couldn’t be opened because URL type https isn’t supported.
Is there a way how to perform this?
You can use NSURLSessionDownloadTask to download the file:
func downloadFile(url: URL) {
let downloadRequest = URLRequest(url: url)
URLSession.shared.downloadTask(with: downloadRequest) { location, response, error in
// To do check resoponse before saving
guard let tempLocation = location where error == nil else { return }
let documentDirectory = FileManager.default.urlsForDirectory(.documentDirectory, inDomains: .userDomainMask).last
do {
let fullURL = try documentDirectory?.appendingPathComponent((response?.suggestedFilename!)!)
try FileManager.default.moveItem(at: tempLocation, to: fullURL!)
print("saved at \(fullURL) ")
} catch NSCocoaError.fileReadNoSuchFileError {
print("No such file")
} catch {
// other errors
print("Error downloading file : \(error)")
}
}.resume()
}
let stringURL = "https://wordpress.org/plugins/about/readme.txt"
downloadImage(url: URL(string: stringURL)!)
Update: SWIFT 2.2
func downloadFile(url: NSURL) {
let downloadRequest = NSURLRequest(URL: url)
NSURLSession.sharedSession().downloadTaskWithRequest(downloadRequest){ (location, response, error) in
guard let tempLocation = location where error == nil else { return }
let documentDirectory = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first
let fullURL = documentDirectory?.URLByAppendingPathComponent((response?.suggestedFilename)!)
do {
try NSFileManager.defaultManager().moveItemAtURL(tempLocation, toURL: fullURL!)
} catch NSCocoaError.FileReadNoSuchFileError {
print("No such file")
} catch {
print("Error downloading file : \(error)")
}
}.resume()
}
let stringURL = "https://wordpress.org/plugins/about/readme.txt"
let url = NSURL.init(string: stringURL)
downloadFile(url!)
You should download it first, then save it to a local file.
Code example can be found here: (using AFNetworking)
How I properly setup an AFNetworking Get Request?
I want to build an app which also includes the possibility to show and save PDFs inside the app and display them (as a FileSystem) within a tableview and open them when I tap on one PDF.
Here are my important questions for that:
1. How do I save a PDF local on my app ( for example if the user can enter a url) and where exactly will it save it ?
2. When saved, how can I show all the local storaged files within a tableview to open them?
Since several people requested this, here is the equivalent to the first answer in Swift:
//The URL to Save
let yourURL = NSURL(string: "http://somewebsite.com/somefile.pdf")
//Create a URL request
let urlRequest = NSURLRequest(URL: yourURL!)
//get the data
let theData = NSURLConnection.sendSynchronousRequest(urlRequest, returningResponse: nil, error: nil)
//Get the local docs directory and append your local filename.
var docURL = (NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)).last as? NSURL
docURL = docURL?.URLByAppendingPathComponent( "myFileName.pdf")
//Lastly, write your file to the disk.
theData?.writeToURL(docURL!, atomically: true)
Also, since this code uses a synchronous network request, I highly recommend dispatching it to a background queue:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
//The URL to Save
let yourURL = NSURL(string: "http://somewebsite.com/somefile.pdf")
//Create a URL request
let urlRequest = NSURLRequest(URL: yourURL!)
//get the data
let theData = NSURLConnection.sendSynchronousRequest(urlRequest, returningResponse: nil, error: nil)
//Get the local docs directory and append your local filename.
var docURL = (NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)).last as? NSURL
docURL = docURL?.URLByAppendingPathComponent( "myFileName.pdf")
//Lastly, write your file to the disk.
theData?.writeToURL(docURL!, atomically: true)
})
And the answer to second question in Swift:
//Getting a list of the docs directory
let docURL = (NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).last) as? NSURL
//put the contents in an array.
var contents = (NSFileManager.defaultManager().contentsOfDirectoryAtURL(docURL!, includingPropertiesForKeys: nil, options: NSDirectoryEnumerationOptions.SkipsHiddenFiles, error: nil))
//print the file listing to the console
println(contents)
Swift 4.1
func savePdf(urlString:String, fileName:String) {
DispatchQueue.main.async {
let url = URL(string: urlString)
let pdfData = try? Data.init(contentsOf: url!)
let resourceDocPath = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last! as URL
let pdfNameFromUrl = "YourAppName-\(fileName).pdf"
let actualPath = resourceDocPath.appendingPathComponent(pdfNameFromUrl)
do {
try pdfData?.write(to: actualPath, options: .atomic)
print("pdf successfully saved!")
} catch {
print("Pdf could not be saved")
}
}
}
func showSavedPdf(url:String, fileName:String) {
if #available(iOS 10.0, *) {
do {
let docURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let contents = try FileManager.default.contentsOfDirectory(at: docURL, includingPropertiesForKeys: [.fileResourceTypeKey], options: .skipsHiddenFiles)
for url in contents {
if url.description.contains("\(fileName).pdf") {
// its your file! do what you want with it!
}
}
} catch {
print("could not locate pdf file !!!!!!!")
}
}
}
// check to avoid saving a file multiple times
func pdfFileAlreadySaved(url:String, fileName:String)-> Bool {
var status = false
if #available(iOS 10.0, *) {
do {
let docURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let contents = try FileManager.default.contentsOfDirectory(at: docURL, includingPropertiesForKeys: [.fileResourceTypeKey], options: .skipsHiddenFiles)
for url in contents {
if url.description.contains("YourAppName-\(fileName).pdf") {
status = true
}
}
} catch {
print("could not locate pdf file !!!!!!!")
}
}
return status
}
I am giving an example of storing and retrieving a pdf document in iOS. I hope that is what you are looking for.
1. How do I save a PDF local on my app ( for example if the user can enter a url) and where exactly will it save it ?
// the URL to save
NSURL *yourURL = [NSURL URLWithString:#"http://yourdomain.com/yourfile.pdf"];
// turn it into a request and use NSData to load its content
NSURLRequest *request = [NSURLRequest requestWithURL:result.link];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// find Documents directory and append your local filename
NSURL *documentsURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
documentsURL = [documentsURL URLByAppendingPathComponent:#"localFile.pdf"];
// and finally save the file
[data writeToURL:documentsURL atomically:YES];
2. When saved, how can I show all the local storaged files within a tableview to open them?
You can check that the file has downloaded, or you can list the Documents directory like so:
// list contents of Documents Directory just to check
NSURL *documentsURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSArray *contents = [[NSFileManager defaultManager]contentsOfDirectoryAtURL:documentsURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsHiddenFiles error:nil];
NSLog(#"%#", [contents description]);
Downloading and displaying PDF in Webview using Swift.
let request = URLRequest(url: URL(string: "http://<your pdf url>")!)
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let task = session.dataTask(with: request, completionHandler: {(data, response, error) in
if error == nil{
if let pdfData = data {
let pathURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("\(filename).pdf")
do {
try pdfData.write(to: pathURL, options: .atomic)
}catch{
print("Error while writting")
}
DispatchQueue.main.async {
self.webView.delegate = self
self.webView.scalesPageToFit = true
self.webView.loadRequest(URLRequest(url: pathURL))
}
}
}else{
print(error?.localizedDescription ?? "")
}
}); task.resume()
If you want to store file in Files app add`
NSURL *url = [NSURL URLWithString:#"PATH TO PDF"];
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithURL:url inMode:UIDocumentPickerModeExportToService];
[documentPicker setDelegate:self];
[self presentViewController:documentPicker animated:YES completion:nil];
And here are delegate methods
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
}
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
}
It will open a DocumentPickerViewController where you can choose a folder to store the file.
Requires iOS11 or later.
if you want to print the PDF data wich is in the directoryURL then use :
let printInfo = NSPrintInfo.shared
let manager = FileManager.default
do{
let directoryURL = try manager.url(for: .documentDirectory, in:.userDomainMask, appropriateFor:nil, create:true)
let docURL = NSURL(string:"LadetagMahlzeiten.pdf", relativeTo:directoryURL)
let pdfDoc = PDFDocument.init(url: docURL! as URL)
let page = CGRect(x: 0, y: 0, width: 595.2, height: 1841.8) // A4, 72 dpi
let pdfView : PDFView = PDFView.init(frame: page)
pdfView.document = pdfDoc
let operation: NSPrintOperation = NSPrintOperation(view: pdfView, printInfo: printInfo)
operation.printPanel.options.insert(NSPrintPanel.Options.showsPaperSize)
operation.printPanel.options.insert(NSPrintPanel.Options.showsOrientation)
operation.run()
}catch{
}
//savePdf(urlString:url, fileName:fileName)
let urlString = "here String with your URL"
let url = URL(string: urlString)
let fileName = String((url!.lastPathComponent)) as NSString
// Create destination URL
let documentsUrl:URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!
let destinationFileUrl = documentsUrl.appendingPathComponent("\(fileName)")
//Create URL to the source file you want to download
let fileURL = URL(string: urlString)
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url:fileURL!)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully downloaded. Status code: \(statusCode)")
}
do {
try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
do {
//Show UIActivityViewController to save the downloaded file
let contents = try FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
for indexx in 0..<contents.count {
if contents[indexx].lastPathComponent == destinationFileUrl.lastPathComponent {
let activityViewController = UIActivityViewController(activityItems: [contents[indexx]], applicationActivities: nil)
self.present(activityViewController, animated: true, completion: nil)
}
}
}
catch (let err) {
print("error: \(err)")
}
} catch (let writeError) {
print("Error creating a file \(destinationFileUrl) : \(writeError)")
}
} else {
print("Error took place while downloading a file. Error description: \(error?.localizedDescription ?? "")")
}
}
task.resume()
}
For Swift 5 and up Version: Save PDF base64 String Data to Document Directory
Create a Folder where you want to save PDF file with Name
fileprivate func getFilePath() -> URL? {
let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let directoryURl = documentDirectoryURL.appendingPathComponent("Invoice", isDirectory: true)
if FileManager.default.fileExists(atPath: directoryURl.path) {
return directoryURl
} else {
do {
try FileManager.default.createDirectory(at: directoryURl, withIntermediateDirectories: true, attributes: nil)
return directoryURl
} catch {
print(error.localizedDescription)
return nil
}
}
}
Write PDF base64 String Data to Document Directory
fileprivate func saveInvoice(invoiceName: String, invoiceData: String) {
guard let directoryURl = getFilePath() else {
print("Invoice save error")
return }
let fileURL = directoryURl.appendingPathComponent("\(invoiceName).pdf")
guard let data = Data(base64Encoded: invoiceData, options: .ignoreUnknownCharacters) else {
print("Invoice downloaded Error")
self.hideHUD()
return
}
do {
try data.write(to: fileURL, options: .atomic)
print("Invoice downloaded successfully")
} catch {
print(error.localizedDescription)
}
}