33

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 ?

Rufus
  • 640
  • 1
  • 7
  • 14

2 Answers2

38

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.
Code Different
  • 90,614
  • 16
  • 144
  • 163
  • Where does it say UIWebView is deprecated? – jjxtra Jun 12 '17 at 15:22
  • It does not say "deprecated", just "use the WKWebView class instead of using UIWebView". And source code has not been marked as deprecated or with a warning. They don't give more details, so it is not clear to me. – Ricardo Aug 02 '17 at 08:42
  • there's nothing mention on `UIWebView` class reference till date but Just now I saw in Xcode 9 beta 6 that at the place where all UI component listing on storyboard editor, `UIWebView` deprecated. – Suryakant Sharma Sep 01 '17 at 06:33
  • The challenge here is that data detectors in WKWebView appear to only support iOS 10+, which is a issue for our user base. Anyone have a way to stick with WKWebView and detect links in iOS 9? – Rob Bonner Apr 20 '18 at 15:56
  • UIWebView is marked as deprecated as of iOS 12: https://developer.apple.com/documentation/uikit/uiwebview – Apoorv Khatreja Jun 04 '18 at 23:08
  • 1
    To clarify the timeline in the above comments: At the time of jjxtra's post, there was a note at the top of the [documentation](https://developer.apple.com/documentation/uikit/uiwebview) instructing developers not to use it UIWebView for iOS8+ apps. This doesn't constitute explicit deprecation, though I recommend treating such notes as deprecation for purposes of developer decision-making; it's still an official recommendation. On the other hand, now it has been explicitly marked deprecated. – Brian Sep 05 '18 at 19:30
  • ITMS-90809: Deprecated API Usage - Apple will stop accepting submissions of new apps that use UIWebView APIs starting from April 2020. See https://developer.apple.com/documentation/uikit/uiwebview for more information. After you’ve corrected the issues, you can upload a new binary to App Store Connect. – billa-code Apr 30 '20 at 07:58
3

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

Ryan H.
  • 2,543
  • 1
  • 15
  • 24