WKWebView not loading local files under iOS 8 WKWebView not loading local files under iOS 8 swift swift

WKWebView not loading local files under iOS 8


They finally solved the bug! Now we can use -[WKWebView loadFileURL:allowingReadAccessToURL:]. Apparently the fix was worth some seconds in WWDC 2015 video 504 Introducing Safari View Controller

https://developer.apple.com/videos/wwdc/2015/?id=504

For iOS8 ~ iOS10 (Swift 3)

As Dan Fabulish's answer states this is a bug of WKWebView which apparently is not being solved any time soon and as he said there is a work-around :)

I am answering just because I wanted to show the work-around here. IMO code shown in https://github.com/shazron/WKWebViewFIleUrlTest is full of unrelated details most people are probably not interested in.

The work-around is 20 lines of code, error handling and comments included, no need of a server :)

func fileURLForBuggyWKWebView8(fileURL: URL) throws -> URL {    // Some safety checks    if !fileURL.isFileURL {        throw NSError(            domain: "BuggyWKWebViewDomain",            code: 1001,            userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("URL must be a file URL.", comment:"")])    }    try! fileURL.checkResourceIsReachable()    // Create "/temp/www" directory    let fm = FileManager.default    let tmpDirURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("www")    try! fm.createDirectory(at: tmpDirURL, withIntermediateDirectories: true, attributes: nil)    // Now copy given file to the temp directory    let dstURL = tmpDirURL.appendingPathComponent(fileURL.lastPathComponent)    let _ = try? fm.removeItem(at: dstURL)    try! fm.copyItem(at: fileURL, to: dstURL)    // Files in "/temp/www" load flawlesly :)    return dstURL}

And can be used as:

override func viewDidLoad() {    super.viewDidLoad()    var fileURL = URL(fileURLWithPath: Bundle.main.path(forResource:"file", ofType: "pdf")!)    if #available(iOS 9.0, *) {        // iOS9 and above. One year later things are OK.        webView.loadFileURL(fileURL, allowingReadAccessTo: fileURL)    } else {        // iOS8. Things can (sometimes) be workaround-ed        //   Brave people can do just this        //   fileURL = try! pathForBuggyWKWebView8(fileURL: fileURL)        //   webView.load(URLRequest(url: fileURL))        do {            fileURL = try fileURLForBuggyWKWebView8(fileURL: fileURL)            webView.load(URLRequest(url: fileURL))        } catch let error as NSError {            print("Error: " + error.debugDescription)        }    }}


WKWebView can't load content from file: URLs via its loadRequest: method. http://www.openradar.me/18039024

You can load content via loadHTMLString:, but if your baseURL is a file: URL, then it still won't work.

iOS 9 has a new API that will do what you want, [WKWebView loadFileURL:allowingReadAccessToURL:].

There is a workaround for iOS 8, demonstrated by shazron in Objective-C here https://github.com/shazron/WKWebViewFIleUrlTest to copy files into /tmp/www and load them from there.

If you're working in Swift, you could try nachos4d's sample instead. (It's also much shorter than shazron's sample, so if you're having trouble with shazron's code, give that a try instead.)


An example of how to use [WKWebView loadFileURL:allowingReadAccessToURL:] on iOS 9.

When you are moving the web folder to a project, select "Create folder references"

enter image description here

Then use code that is something like this(Swift 2):

if let filePath = NSBundle.mainBundle().resourcePath?.stringByAppendingString("/WebApp/index.html"){  let url = NSURL(fileURLWithPath: filePath)  if let webAppPath = NSBundle.mainBundle().resourcePath?.stringByAppendingString("/WebApp") {    let webAppUrl = NSURL(fileURLWithPath: webAppPath, isDirectory: true)    webView.loadFileURL(url, allowingReadAccessToURL: webAppUrl)  }}

In the html file use filepaths like this

<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">

not like this

<link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet">

An example of directory that is moved to a xcode project.

enter image description here