Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 ?

like image 509
Rufus Avatar asked Dec 14 '16 03:12

Rufus


People also ask

What is the difference between UIWebView and WKWebView?

One major architectural difference between UIWebView and WKWebView is that the methods of WKWebView tend to be asynchronous, while the methods of UIWebView were synchronous.

What does UIWebView mean?

Android is powered by Chrome. Mobile Safari UIWebView. The UIWebView is different from the ordinary Safari browser, as it is not a stand-alone browser, but merely browser functionality that is embedded in a third party app that allows the app to display content from the web.

Is WKWebView the same as Safari?

WKWebView - This view allows developers to embed web content in your app. You can think of WKWebView as a stripped-down version of Safari. It is responsible to load a URL request and display the web content. WKWebView has the benefit of the Nitro JavaScript engine and offers more features.


2 Answers

A couple points:

  1. 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.

  1. 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.
like image 132
Code Different Avatar answered Oct 10 '22 17:10

Code Different


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

like image 42
Ryan H. Avatar answered Oct 10 '22 15:10

Ryan H.