wkwebview cant loading base url from documentsURL - ios

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")
}

Related

Load image from local URL file with path

In my application, I am writing an image to a URL file and saving the relative URL in order to retrieve the image later on. This is what I am doing, but it is not working. Is there anything you see wrong.
let imageRelativeURL = pendingPostData[2]
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let urlString = "\(documentsPath)/\(imageRelativeURL).jpg"
let image = UIImage(contentsOfFile: urlString)
// This is the line that is causing the error
let imageData = UIImageJPEGRepresentation(image!, 1.0)
I am getting this error:
Thread 1: FATAL ERROR: Unexpectedly found nil while wrapping an Optional Value
This is how I am saving the relative URL.
let uniqueRelativeID = NSUUID().uuidString
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let outputPath = "\(documentsPath)/\(uniqueRelativeID).jpg"
let relativePath = "\(uniqueRelativeID).jpg"
let relativeURL = URL(fileURLWithPath: relativePath)
let imageURL = URL(fileURLWithPath: outputPath, relativeTo: relativeURL)
do {
try UIImageJPEGRepresentation(chosenImg, 1.0)?.write(to: imageURL)
} catch {
print("There was a problem writing image file.")
}
saveVideoData(data: imageURL.relativeString)

PDF is generated but file not retrieved in a webView in swift ios

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!)

Unable to load pdf from document directory in Swift

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")
}

UIDocumentInteractionController open url

I have url with pdf extension. On tapping the url, I want to show user with options to open URL with apps (which should include safari browser as well). I might achieve this by first downloading file from url in document directory and then open the file. But I don't want to download the file, rather I want to give user options to open that url. This is what I have tried for first downloading and then opening the file but even this is not showing up the options to pick the apps :
func openDocument(document: Document)
{
let url = URL(string: document.documentUrl)
var urlData = Data()
do
{
urlData = try Data(contentsOf: url!)
}
catch
{
}
if urlData != nil {
var paths: [Any] = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let temp = NSURL.fileURL(withPath: NSTemporaryDirectory(), isDirectory: true)
// let temp = NSURL(
let targetPath = temp.appendingPathComponent("\("name").pdf")
do
{
//try urlData.write(to: URL(fileURLWithPath: targetPath), options: .atomic)
try urlData.write(to: targetPath, options: .atomic)
}
catch let error as NSError {
print("Could not write file", error.localizedDescription)
}
}
var paths: [Any] = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let temp = NSURL.fileURL(withPath: NSTemporaryDirectory(), isDirectory: true)
let targetPath = temp.appendingPathComponent("\("name").pdf")
let pdfUrl = URL(fileURLWithPath: targetPath.absoluteString)
if pdfUrl != nil {
documentInteractionController = UIDocumentInteractionController(url: pdfUrl)
documentInteractionController.name = document.documentName
documentInteractionController.delegate = self
documentInteractionController.presentPreview(animated: true)
}
}

Download PDF, saving to document directory and loading it in UIWebView

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")

Resources