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")
}
Related
I am generating a PDF of a UIView and storing with a name in myforms the PFD is being generated and console prints PDF is Available but it shows nothing but a white screen in VC
here is what I am doing :
I have this code to generate a PDF
#IBAction func createAct(_ sender: Any) {
print("Creat PDF")
self.createPdfFromView(mainView: mainView, saveToDocumentsWithFileName: "myforms")
}
func createPdfFromView(mainView: UIView, saveToDocumentsWithFileName fileName: String)
{
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, mainView.bounds, nil)
UIGraphicsBeginPDFPage()
guard let pdfContext = UIGraphicsGetCurrentContext() else { return }
mainView.layer.render(in: pdfContext)
UIGraphicsEndPDFContext()
if let documentDirectories = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
let documentsFileName = documentDirectories + "/" + fileName
debugPrint(documentsFileName)
pdfData.write(toFile: documentsFileName, atomically: true)
}
}
then I have this in console :
Creat PDF
"/Users/jawaidahmed/Library/Developer/CoreSimulator/Devices/3F95BE09-0F25-427C-9ED9-4BDB16DC3600/data/Containers/Data/Application/1EC22FBC-79E7-4AC5-BB7D-13783CC34516/Documents/myforms"
and I am using this PDFViewController to retrieve the file in a webview
override func viewDidLoad() {
super.viewDidLoad()
let check = "myforms"
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: "myforms", withExtension: nil, subdirectory: 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")
filePath = "file://\(filePath)"
let fileUrlkk = Foundation.URL(string: filePath)
let data = try Data(contentsOf: fileUrlkk!)
self.webView.load(data, mimeType: filePath, textEncodingName:"utf-8", baseURL: pdfURL.deletingLastPathComponent())
} else {
print("FILE NOT AVAILABLE in VC")
}
}
catch let error as NSError {
print("An error took place: \(error)")
}
}
And I am receiving this in console :
FILE AVAILABLE in VC
It means file is generated and available but it shows only empty VC white background only
self.webView.load(data, mimeType: "application/pdf", textEncodingName:"utf-8", baseURL: pdfURL.deletingLastPathComponent())
replace textEncodingName:""
with
textEncodingName:"utf-8"
check it
Try this for loading in Webview.I tried with your sample..It works
let FileName = "myforms"
let Filemanager = NSFileManager.defaultManager()
let docURL = Filemanager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL
print(docURL)
let pdfPATH = docURL.URLByAppendingPathComponent(FileName)
print(pdfPATH)
let data = NSData(contentsOfURL: pdfPATH)
WBview.loadData(data!, MIMEType: "application/pdf", textEncodingName: "utf-8", baseURL: pdfPATH.URLByDeletingLastPathComponent!)
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 am downloading file from firebase. let say the request url is following
social-cam-storage/albm-72/owner-2/1484043313786.jpeg
i can download the file using the following code
func downloadFile(url : String) {
let storageR = FIRStorage.storage().reference(withPath: url)
let maxSize : Int64 = 3 * 1024 * 1024 // 3MB
storageR.data(withMaxSize: maxSize) { (data, error) in
if error != nil {
print(error.debugDescription)
return
}
print(data!)
}
}
Now i need to store this data maintaining the directory structure of the url
I have tried
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
print(FileManager.default.createFile(atPath: "\(documentsURL.absoluteString)/\(url)", contents: data!, attributes: nil))
but i am getting false
so how to fix this or is there any other way to save??
Have you tried something like this? :
If you have the exact path already as a string:
try? data.write(to: URL(fileURLWithPath: path), options: [.atomic])
If you need the path there are a few methods:
func saveFile() {
let filePath = getDocumentsURL().absoluteString.appending(path)
try? data.write(to: URL(fileURLWithPath: filePath), options: [.atomic])
}
func getDocumentsURL() -> URL {
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
return documentsURL
}
You could also just try saving the filename, and then loading later when you need it:
func fileInDocumentsDirectory(_ filename: String) -> String {
let fileURL = getDocumentsURL().appendingPathComponent(filename)
return fileURL.path
}
// To save file
func saveFile(data: Data) {
let fileName:String = "createUniqueFileName"
let filePath = fileInDocumentsDirectory(fileName)
saveData(data, filePath)
}
// To load file with saved file name
func loadFile(fileName: String) {
if let loadedData = loadData(fileName) {
// Handle data however you wish
}
}
func saveData(_ data: Data, path: String ) {
try? data.write(to: URL(fileURLWithPath: path), options: [.atomic])
}
func loadData(_ path: String) -> Data? {
let data:Data? = try? Data(contentsOf: URL(fileURLWithPath: path))
return data
}
Have you tried using the built in "download to file" API in Firebase Storage?
// Create a reference to the file you want to download
let fileURL = storage.reference(withPath: url)
// Create local filesystem URL
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = ...
// Download to the local filesystem
let downloadTask = islandRef.write(toFile: fileURL) { url, error in
if let error = error {
// Uh-oh, an error occurred!
} else {
// Local file URL is returned
}
}
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")
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");
}