Saving PDF Files with Swift in iOS and display them
Solution 1
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)
Solution 2
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
}
Solution 3
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]);
Solution 4
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.
Solution 5
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()
MkaysWork
Updated on March 04, 2021Comments
-
MkaysWork about 3 years
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?
-
MkaysWork about 9 yearsThanks for the quick reply! I understand and will try to translate it to swift as soon as I can, or do you even know how to make it with Swift?
-
MkaysWork about 9 yearsI tried it but I couldn't do it. I still have some problems of which datatypes to use.
-
Josip Bogdan almost 9 yearscan u put swift code here, it would be so helpfull, thanks in advance :)
-
vinbhai4u almost 9 years@MkaysWork can you put the swift code please? Thanks a lot :)
-
Ne AS over 7 yearsHi! I tested your code and it works. I can see the path of the file in the console. But where is ,in the device, the Documents folder that I see in the path? What if I want to download the file and then display it? Thanks
-
Satre over 7 yearsHello! I'm glad it worked for you. In terms of absolute paths, I don't know where the app specific Documents directory is on the iPhone. Since Apple intentionally obfuscates the filesystem from developers, you can use the various constants used above to access the specific Documents directory
-
Ne AS over 7 yearsThanks for the answer! So if I understood, I can't see it in the iPhone by accessing to it from a directory or something else. That's it? And another question please: what if I want to take the cotent (the path) of the latest downloaded pdf? Can you please take a look in my issue please? stackoverflow.com/questions/40567952/… thanks a lot!
-
BIJU C about 5 yearsSorry for that, definitely add some explanation.
-
Nico Haase about 5 yearsAnd where is that explanation?
-
jbiser361 over 4 yearswhat is "fileName"
-
Muju about 4 years@BIJUC Where the PDF is save in iPhone?
-
Michael Nelles about 4 yearsWith this solution can I show all the local storage files within a tableview?
-
Bruno Camargos about 4 yearsIt will only try to save, if the file already exists will throw an error
-
Anees almost 4 yearsI found this solution as the best.
-
iMinion over 3 yearsBest solution !
-
Moumen Alisawe about 2 yearsYou are a lifesaver