Force WKWebView to show desktop version - ios

I have a NSViewController which displays various WKWebView at specific locations inside a NSView. If the frame of the WKWebView gets small - it switches to the mobile version of the website. Is there a way to always show the full (desktop version) website in the WKWebView?
My first idea was to inject some javascript and set the viewport to a specific size to force the website to display a "Desktop" view.
let viewportScriptString = "var meta=document.createElement('meta');meta.name=\"viewport\";meta.content=\"width=1920\";document.getElementsByTagName('head')[0].appendChild(meta);"
let viewportScript = WKUserScript(source: viewportScriptString, injectionTime: .AtDocumentStart, forMainFrameOnly: true)
let controller = WKUserContentController()
controller.addUserScript(viewportScript)
let config = WKWebViewConfiguration()
config.userContentController = controller
let nativeWebView = WKWebView(frame: CGRect.zero, configuration: config)
Unfortunately this does not work and the website is still scaled. To demonstrate the behaviour i try to achieve please see the following screenshot.
==EDIT==
thanks for pointing me to some similar questions. I tried the following the solutions that worked for other users. Unfortunately I had no luck. Maybe WKWebView is different on macOS - the other questions are about iOS.
NSUserDefaults
setting the CustomUserAgent on WKWebView
setting ApplicationNameForUserAgent on WKWebViewConfiguration
adding a User-Agent to NSUrlRequest

You should change the user agent, for example:
UserDefaults.standard.register(defaults: ["UserAgent" : "Chrome Safari"])

Related

Share/Reload localStorage, IndexedDB, cookies between WKWebViews

There is a controller with a WKWebView "Parent" that opens (pushes) another controller with another WKWebView "Child".
When Child modifies the localStorage, sessionStorage or IndexedDB then pops back to Parent, Parent is NOT aware of the changes and needs to be reloaded to see the new values set by Child.
It means that both WKWebView share the same localStorage, sessionStorage, indexedDB, but they need a refresh of the content to see the modifications.
How to share in real-time the same storage between WKWebView?
The init of WKWebViews can receive a parameter WKWebViewConfiguration with a variable called processPool that represents all the web content (including localStorage, IndexedDB, cookies and so on) process.
So for the WKWebViews to share in real-time all the memory management, you need to declare a unique WKProcessPool for all of them.
let uniqueProcessPool = WKProcessPool()
let configA = WKWebViewConfiguration()
configA.processPool = uniqueProcessPool
let webViewA = init(frame: CGRect.zero, configuration: configA)
let configB = WKWebViewConfiguration()
configB.processPool = uniqueProcessPool
let webViewB = init(frame: CGRect.zero, configuration: configB)

How to open a document URL in default ios APP using Swft 3?

I have a url document url list in a TableViewController` like this one
https://lists.w3.org/Archives/Public/uri/2004Nov/att-0015/App-Note-UseOfTheFileURLInJDF-031111.doc
and on TableViewCell selection this doc file should open in any default viewer that is not part my app, So I can do achieve this ? Is this possible or any suggestion.
Working with Quick​Look Framework should satisfied your requirement.
As mentioned at "Using the Quick Look Framework":
A Quick Look preview controller can display previews for the following
items:
iWork documents
Microsoft Office documents (Office ‘97 and newer)
Rich Text Format (RTF) documents
PDF files
Images
Text files whose uniform type identifier (UTI) conforms to the public.text type
Comma-separated value (csv) files
You can find many of articles about working with QuickLook Framework; You might want to check the following one:
Using Quick Look Framework for Previewing Documents.
Also, checking this repo (GitHub) might be useful.
Hope this helped.
Use UIWebView class to open the given URL.
Method 1:
let webView = UIWebView(frame: self.view.frame)
webView.scalesPageToFit = true
view.addSubview(webView)
let urlS = "https://lists.w3.org/Archives/Public/uri/2004Nov/att-0015/App-Note-UseOfTheFileURLInJDF-031111.doc"
let url = URL(string: urlS)
let request = URLRequest(url: url!)
webView.loadRequest(request)
Method 2:
With this method, you'll get nice ToolBar items, which you can customize based on your requirement.
Using UIWebView library for Swift, SwiftWebView:
If you're using UINavigationController:
let urlS = "https://lists.w3.org/Archives/Public/uri/2004Nov/att-0015/App-Note-UseOfTheFileURLInJDF-031111.doc"
let webVC = SwiftWebVC(urlString: urlS)
self.navigationController?.pushViewController(webVC, animated: true)
OR
If you want to present Modally:
let urlS = "https://lists.w3.org/Archives/Public/uri/2004Nov/att-0015/App-Note-UseOfTheFileURLInJDF-031111.doc"
let webVC = SwiftModalWebVC(urlString: urlS)
self.present(webVC, animated: true, completion: nil)

What's the difference between UIWebView and WKWebView when loading local resources

I want to load local resources with webView. I built a demo with both UIWebView and WKWebView to do some test with the code below.
let uiWebView = UIWebView(frame: self.view.bounds)
self.view.addSubview(uiWebView)
let wkWebView = WKWebView(frame:CGRect(x: 0, y: 400, width: 500, height: 500))
self.view.addSubview(wkWebView)
let path = Bundle.main.path(forResource:"1", ofType: "png")
guard let realPath = path else {
return
}
let url = URL(string: realPath)
let fileUrl = URL(fileURLWithPath: realPath)
if let realUrl = url {
uiWebView.loadRequest(URLRequest(url:realUrl))
wkWebView.load(URLRequest(url:realUrl))
}
// uiWebView.loadRequest(URLRequest(url:fileUrl))
// wkWebView.load(URLRequest(url:fileUrl))
The uiWebView can load the resource but wkWebView can not. But if I use
uiWebView.loadRequest(URLRequest(url:fileUrl))
wkWebView.load(URLRequest(url:fileUrl))
both uiWebView and wkWebView can work well.
I am confused and can anyone explain that for me:
Shouldn't I use URL(string: realPath) for a local resource? But why UIWebView can use it ?
A couple points:
Apple recommends that you use WKWebview for iOS 8 and later. I would avoid writing new code with UIWebView.
In apps that run in iOS 8 and later, use the WKWebView class instead of using UIWebView. Additionally, consider setting the WKPreferences property javaScriptEnabled to false if you render files that are not supposed to run JavaScript.
Apple has been trying to move away from path and instead wants to use URI even for local files. They recommend that you NOT use /path/to/file.png and use file:///path/to/file.png instead.
As to why one URL works and the other does not, let's make a minimal example:
let realPath = "/path/to/file.png"
let url = URL(string: realPath) // /path/to/file.png
let fileUrl = URL(fileURLWithPath: realPath) // file:///path/to/file.png
url does not provide the scheme (a.k.a protocol). It should only be used in conjunction with another URL to give the absolute address of the resource you are trying to reach. UIWebView supports it for backwards-compatibility reasons but Apple decided to start clean with WKWebView.
fileURL has a scheme (file://) that tells the resource is located on the local file system. Other common schemes are http, https, ftp, etc. It's a complete address to a resource so both views know how to resolve it.
This might be for security reasons, or just how the WKWebView API was implemented.
WKWebView has a specific instance method for loading local resources called loadFileURL(_:allowingReadAccessTo:). This was introduced in iOS 9.
Note
If you are targeting iOS 8.0 or newer, you should be using WKWebView instead of UIWebView. See: https://developer.apple.com/reference/webkit/wkwebview

Swift WKWebView Loading local file not working on a device

I am having some issues when trying to run my app on an iPad (or any device) it runs as expected on the emulator so it is weird that it doesn't work on a device. I was wondering if some one could point me in the correct direction. I spend many hours reading all the other posts on here about the same issues, however none of the suggested solutions worked.
I have a WKWebView into which I am loading a local html file. On the emulator the file loads and everything works fine but on a device I am getting a message in the log:
Could not create a sandbox extension for '/'
Here is the code I have that loads the file into the
override func viewDidLoad() {
super.viewDidLoad()
var path = NSBundle.mainBundle().pathForResource("Login_UK",
ofType: "html")
var url = NSURL(fileURLWithPath: path!)
var request = NSURLRequest(URL: url!)
var theConfiguration = WKWebViewConfiguration()
theConfiguration.userContentController.addScriptMessageHandler(self,
name: "callbackHandler")
webView = WKWebView(frame: self.view.frame,
configuration: theConfiguration)
webView!.loadRequest(request)
self.view.addSubview(webView!)
}
Any help will be greatly appreciated
Kind Regards,
Dimitar
Thank you for any one who tried to answer my question. I have released that this is an error with the WebKit lib that Apple are trying to fix. However I have found a good workaround that required little work.
I open the local file and read its content and then send that string into a webView.loadHTMLString method that compiles the hmtl that was in the file. That way you avoid the issues with iOS not being able to find the path to the local file.
Here is an example of reading a file and then opening it for any one who has the same issues:
let path2 = NSBundle.mainBundle().pathForResource("index", ofType: "html")
var text = String(contentsOfFile: path2!, encoding: NSUTF8StringEncoding, error: nil)!
webView!.loadHTMLString(text, baseURL: url)
Kind regards,
Dimitar
Just do this:
if url.isFileURL {
webView.loadFileURL(url, allowingReadAccessTo: url)
} else {
let request = URLRequest(url: url)
webView.load(request)
}
There is a function loadFileURL on the WKWebView starting iOS 9 that apparently has to be used when reading data from a file URL.
Strange enough using the load function with an URLRequest for the file URL does work in the simulators, but not on device - the web view stays blank on the device. Using the loadFileURL works on device and the simulator.
Using loadHTMLString unfortunately introduces another problem (local anchors that jump to another position in the same web view are not working anymore) and probably should be avoided until Apple releases a fix for that issue.
Actually the problem is caused by the webView.load() function, if we test it on simulators it will work perfectly, but for the real device it may cause some problems and it will not load the webview perfectly. You may check it by calling the didFinish() function.
What you need to do is call webView.loadFileURL() rather than webView.load(). It will work in both simulators and real devices. This is very useful when you load any file from the local file directory.

WKWebView showing blank on device, working on simulator

One of the modules of my app is a web site. That web site contains primarily an SVG drawing, with custom shaped buttons (using Raphael.js library) to access other drawings (other html page with svg drawings).
If the device is on iOS 7, I use a UIWebView and everything works fine.
For iOS 8 devices, I use a WKWebView. I had some issues, some of them resolved by this post. I can see my web site on those simulators (iPhone 5 / iOS 8.0 (12A365) & iPhone 5s / iOS 8.0), but I can't see it on my iPod Touch (5th gen, running iOS 8.0.2). It shows a blank screen.
I don't know what to look for. Any idea?
EDIT
After following #Dan Fabulich's answer (here), I now get a forever-loading webview, that never finishes loading up. His answer tells us that there is a bug with WKWebView when loading html from a string. His answer is to copy the html content into a new subfolder and then call loadRequest from that URL.
Unfortunately, I'm still stuck with a non-working webview. Any clue? What would be a reason for a webview to never finish loading up content?
i had some problem but i solved problem with configuration options. here is my my code.
var a = dic["adi"]?.asString()
var path = NSBundle.mainBundle().pathForResource(a, ofType: "htm" )
var url = NSURL(fileURLWithPath:path!)
var request = NSURLRequest(URL:url!)
var theConfiguration = WKWebViewConfiguration()
theWebView = WKWebView(frame:self.view.frame, configuration: theConfiguration)
var error:NSError?
let text2 = String(contentsOfFile: path!, encoding:NSUTF8StringEncoding, error: &error)
if let theError = error
{
print("\(theError.localizedDescription)")
}
theWebView!.loadHTMLString(text2!, baseURL: nil)
self.view.addSubview(theWebView!)
hope this helps.

Resources