I am having problem with download pdf, saving to document directory and loading it in web view.
I have no experience with download things, saving things to directories and UIWebView before.
Before I ask this question, I've search multiple StackOverflow question and tried my best but it still doesn't work.
First This is how I download the PDF from url and save it to document directory
let myURL = URL(string: "https://example/example/product.pdf")
let urlRequest = NSURLRequest(url: myURL!)
do {
let theData = try NSURLConnection.sendSynchronousRequest(urlRequest as URLRequest, returning: nil)
var docURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last as? NSURL
docURL = docURL?.appendingPathComponent("my.pdf") as NSURL?
try theData.write(to: docURL as! URL)
print("downloaded")
} catch (let writeError) {
print("error : \(writeError)")
}
The application pauses for a while and prints "downloaded"
This is how I check the list of contacts in my document directory
let docURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last)
do{
let contents = try (FileManager.default.contentsOfDirectory(at: docURL!, includingPropertiesForKeys: nil, options: FileManager.DirectoryEnumerationOptions.skipsHiddenFiles))
print("There are")
print(contents)
}
catch (let error)
{
print("error contents \(error)")
}
It prints "There are [file:///private/var/mobile/Containers/Data/Application/DF6A310C-EB7E-405E-9B1B-654486B5D03A/Documents/my.pdf]"
This is how I load the pdf into webView
var webView = UIWebView(frame : vc.view.frame)
webView.scalesPageToFit = true
var paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
var documentsDirectory = paths[0]
var filePath = URL(fileURLWithPath: documentsDirectory).appendingPathComponent("my.pdf").absoluteString
var targetURL = URL(fileURLWithPath: filePath)
var request = URLRequest(url: targetURL)
webView.loadRequest(request)
vc.view.addSubview(webView)
The WebView comes up but shows nothing. I'm really confused if my.pdf is really saved with readable PDF format.
I don't know if there are some stuffs like I have to add something in info.plist or enable something in app capabilities. Thank you very much.
I didn't look through all of the code but the following two lines are a problem:
var filePath = URL(fileURLWithPath: documentsDirectory).appendingPathComponent("my.pdf").absoluteString
var targetURL = URL(fileURLWithPath: filePath)
The value of URL absoluteString does not give you a file path so the value of filePath is not a valid value for the URL fileURLWithPath: initializer.
And what's the point of going from URL to String (as a path) and back to a URL? Simply combine those two lines into:
var targetURL = URL(fileURLWithPath: documentsDirectory).appendingPathComponent("my.pdf")
As a side note, use some consistency. In other code you get the Documents folder URL using:
let docURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last)
and in other code you use:
var paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
var documentsDirectory = paths[0]
var ... = URL(fileURLWithPath: documentsDirectory)...
Pick one approach and use it consistently. Since you need a URL, use the first approach. This means the code I suggested should now be:
let docURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last!
let targetURL = docURL.appendingPathComponent("my.pdf")
Related
I'm working on an iOS application. In the app, I am using Alamofire to create a POST request that returns a raw PDF file in response. Right now, I am able to save the file and open it with UIDocumentInteractionController. But, I want the file to stay in User's documents folder.
Here's how I create the destination path:
let destination: DownloadRequest.DownloadFileDestination = { _, _ in
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileURL = documentsURL.appendingPathComponent("Dividend Summary Report.pdf")
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
Someone please tell me what's wrong with my logic and what I can do to correct it.
Well you need to check the file status if it exists then read from documentDirectory else download the file.
Create function like this:
func checkIfFileExists(urlString: String) {
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let url = NSURL(fileURLWithPath: path)
let fileName = urlString
let fileManager = FileManager.default
let filePath = url.appendingPathComponent("\(fileName).pdf")?.path
print("filePath : \(String(describing: filePath))")
if fileManager.fileExists(atPath: filePath!) {
print("File exists")
} else {
print("File doesn't exists")
// set your download function here
}
}
// here frit i want to save a mp4 file before saving i want to check is it alreday there.if there than create another name
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let savePathUrl = NSURL(string: ("\(documentsURL.appendingPathComponent("temp"))" + ".mp4"))
if FileManager.default.fileExists(atPath: **savePathUrl**)// here i get error
}
{
do
{
try FileManager.default.removeItem(atPath: **savePathUrl**)// here i get error
}
catch { }
}
First off, the way you create savePathUrl makes little sense. Replace:
let savePathUrl = NSURL(string: ("\(documentsURL.appendingPathComponent("temp"))" + ".mp4"))
with:
let savePathUrl = documentsURL.appendingPathComponent("temp.mp4")
And then for the two FileManager manager methods you need a file path. To get a file path from a file URL, you need to use the path property.
if FileManager.default.fileExists(atPath: savePathUrl.path) {
I have downloaded a pdf from remote server and saved it in document directory. Now I'm trying to retrieve it and display the pdf in the webView but I keep getting this exception:
failed to find PDF header: `%PDF' not found.
before this exception it showing this exception as well:
objc[8087]: Class PLBuildVersion is implemented in both /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/PrivateFrameworks/AssetsLibraryServices.framework/AssetsLibraryServices (0x11f29dcc0) and /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/PrivateFrameworks/PhotoLibraryServices.framework/PhotoLibraryServices (0x11f0b46f0).
One of the two will be used. Which one is undefined.
But I have noticed that when I try to run from mobile instead of emulator then this second exception is gone. Below is my code for fetching it:
let check:String = FileNames[0] + ".pdf"
print("check = \(check)")
// Method 1
let docURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let targetURL = docURL.appendingPathComponent(check)
var request = URLRequest(url: targetURL)
webView.loadRequest(request)
/*
// Method 2
var pdfURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! as URL
pdfURL = pdfURL.appendingPathComponent(check) as URL
print("check url = \(pdfURL)")
let data = try! Data(contentsOf: pdfURL)
print("check data = \(data)")
webView.load(data, mimeType: "application/pdf", textEncodingName:"utf-8", baseURL: pdfURL) // pdfURL.deletingLastPathComponent()
*/
//let requestk = NSURLRequest(url: pdfURL as URL)
// webView.loadRequest(requestk as URLRequest)
// Method 3
/* let fileManager = FileManager.default
let documentsUrl = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0] as NSURL
var pdf = documentsUrl.appendingPathComponent(check)
print("check item fetching from documentsUrl = \(pdf)")
let req = NSURLRequest(url: pdf!)
self.webView.loadRequest(req as URLRequest)
*/
I have searched a lot about this exception and followed all the possible solutions but none of it is working. But if I try to display this pdf directly from the remote server's address it is getting displayed. And also I have checked that this pdf is stored correctly. I have tried loading through both webView.loadRequest and webView.load with data method, maybe I'm missing something small.
Update
var pdfURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last! as URL
print("check final = \(pdfURL)")
pdfURL = pdfURL.appendingPathComponent(check) as URL
do{
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let url = URL(fileURLWithPath: path)
var filePath = url.appendingPathComponent(check).path
let fileManager1 = FileManager.default
if fileManager1.fileExists(atPath: filePath) {
print("FILE AVAILABLE in VC")
// let fileUrlkk = NSURL(string: filePath)// converting string into URL
filePath = "file://\(filePath)"
let fileUrlkk = Foundation.URL(string: filePath)
let data = try Data(contentsOf: fileUrlkk!)
// let data = try Data(contentsOf: pdfURL) // tried but didn’t work
self.webView.load(data, mimeType: "application/pdf", textEncodingName:"", baseURL: pdfURL.deletingLastPathComponent())
} else {
print("FILE NOT AVAILABLE in VC")
}
}
catch let error as NSError {
print("An error took place: \(error)")
}
it displays "FILE AVAILABLE in VC" but still with this exception.
Use below code to load PDF in WebView
Swift 3.0
var pdfURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last! as URL
pdfURL = pdfURL.appendingPathComponent("Swift.pdf") as URL
let data = try! Data(contentsOf: pdfURL)
self.webView.load(data, mimeType: "application/pdf", textEncodingName:"", baseURL: pdfURL.deletingLastPathComponent())
Where pdf file store in Document directory here is the path.
/Documents/Swift.pdf
----- UPDATE ------
Create new project.
Drag 1 sample PDF in bundle "sample.pdf"
And change your controller code with below
that's it run
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
let check = "Swift.pdf"
var pdfURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last! as URL
print("check final = \(pdfURL)")
pdfURL = pdfURL.appendingPathComponent(check) as URL
if let pdfBundleURL = Bundle.main.url(forResource: "sample", withExtension: "pdf", subdirectory: nil, localization: nil) {
do {
let data = try Data(contentsOf: pdfBundleURL)
//Lastly, write your file to the disk.
try data.write(to: pdfURL, options: .atomicWrite)
}
catch {
// catch errors here
}
}
do{
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let url = URL(fileURLWithPath: path)
var filePath = url.appendingPathComponent(check).path
let fileManager1 = FileManager.default
if fileManager1.fileExists(atPath: filePath) {
print("FILE AVAILABLE in VC")
// let fileUrlkk = NSURL(string: filePath)// converting string into URL
filePath = "file://\(filePath)"
let fileUrlkk = Foundation.URL(string: filePath)
let data = try Data(contentsOf: fileUrlkk!)
// let data = try Data(contentsOf: pdfURL) // tried but didn’t work
self.webView.load(data, mimeType: "application/pdf", textEncodingName:"", baseURL: pdfURL.deletingLastPathComponent())
} else {
print("FILE NOT AVAILABLE in VC")
}
}
catch let error as NSError {
print("An error took place: \(error)")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
just use
do{
let directoryURL = try manager.url(for:.documentDirectory,in:.userDomainMask, appropriateFor:nil, create:true)
let docURL = NSURL(string:"XXX.pdf", relativeTo:directoryURL)
}
catch{print("ERROR")
}
Webkit loading from .documentsURL html webpages, iOS device is not showing image, js, css files, works fine on simulators. What could be my bug in the code I have written?
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let documentsURL = URL(fileURLWithPath: documentsPath, isDirectory: true)
let urltostr = documentsURL.absoluteString
//print(urltostr)
let htmlurl = urltostr+"0/index.html"
let finalURL = URL(string: htmlurl)
let base = urltostr+"0/"
let baseUrl = URL(string: base)
//let baseUrl = URL(fileURLWithPath: base, isDirectory: true)
do {
let fileName = try String(contentsOf: finalURL!)
webview.loadHTMLString(fileName as String, baseURL: baseUrl)
} catch {
// catch error
print("Error web view get html")
}
I seem to be having issues while loading a PDF to my WebView in Swift.
Printing out all the files in the Documents directory results in:
file:///Users/adriandavidsmith/Library/Developer/CoreSimulator/Devices/B537EBE4-14AE-439A-B84B-31342E233367/data/Containers/Data/Application/E791BF20-CC53-4FBB-B34A-F73CED74EB5D/Documents/DOCUMENT.pdf
However, when I attempt to load that file into a WebView nothing gets shown. As if it is unable to find the file.
if let pdf = NSBundle.mainBundle().URLForResource("DOCUMENT", withExtension: "pdf", subdirectory: "Documents", localization: nil){
let req = NSURLRequest(URL: pdf)
webView.loadRequest(req)
Any thoughts/ideas?
Swift 3 compatible
var pdfURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last! as URL
pdfURL = pdfURL.appendingPathComponent( "example.pdf") as URL
let data = try! Data(contentsOf: pdfURL)
let webView = WKWebView(frame: CGRect(x:20,y:20,width:view.frame.size.width-40, height:view.frame.size.height-40))
webView.load(data, mimeType: "application/pdf", characterEncodingName:"", baseURL: pdfURL.deletingLastPathComponent())
view.addSubview(webView)
The E791BF20-CC53-4FBB-B34A-F73CED74EB5D is application folder in which you have Documents folder containing the pdf file which you want to view.
This will give path of Documents folder.
let fileManager = NSFileManager.defaultManager()
let documentsUrl = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL
print(documentsUrl)
You need to change code
let pdf = documentsUrl + "/<your pdf file name>"
let req = NSURLRequest(URL: pdf)
webView.loadRequest(req)
Hope this works for you.
You are fetching it from bundle not from document directory.
Try this....
var pdf = (NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)).last as? NSURL
pdf = pdf?.URLByAppendingPathComponent( "ST_Business%20Times_07022016.pdf")
let req = NSURLRequest(URL: pdf)
webView.loadRequest(req)
Please check you path has valid file exist or not before loading the file.
let webView : UIWebView!
webView = UIWebView()
webView.frame = self.view.bounds
self.view.addSubview(webView)
let PDF_FILE_PATH = NSBundle.mainBundle().pathForResource("ST_Business%20Times_07022016", ofType: "pdf")
let checkValidation = NSFileManager.defaultManager()
if (checkValidation.fileExistsAtPath(PDF_FILE_PATH!))
{
print("FILE AVAILABLE");
let req = NSURLRequest(URL: NSURL(string: PDF_FILE_PATH!)!)
webView.loadRequest(req)
}
else
{
print("FILE NOT AVAILABLE");
}