WKWebView load local web files and resources with Swift

In some situations loading a local web file or resource can be useful, so in this tutorial we will learn how to load a local html file that uses css.

Step 1: Add the web files to your project

To use these local web files in our project, we need to add them to the project.

Once you have clicked "Add Files to", you will be prompted to select the files/folders that you want to add to your project. When you see the below dialog, make sure that you have selected the correct targets as well as "Copy items if needed" and "Create folder references" as you can see in the below image.

In the above image I have selected my index.html as well as my style.css files. My index.html uses the style.css so I need to add box files to the project.

Step 2: Loading the local web files in WKWebView

Loading local web files is really easy. We will learn how to do that in this step. For this tutorial I will assume that you have a WKWebView setup already, if not, I will have the full project linked at the end of this tutorial.

This is my current ViewController.swift:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

I have only added a WKWebView outlet, the rest is standard. This code will not compile, to make it compile we need to import WebKit.

To import WebKit add the following line below import UIKit:

import WebKit

The code will now compile. If I run my app I get a white screen. We can now load the the local files.

To load a local file we need to use the following code:

// 1
if let indexURL = Bundle.main.url(forResource: "index",
                                  withExtension: "html") {
            
    // 2
    self.webView.loadFileURL(indexURL,
                             allowingReadAccessTo: indexURL)
}
  1. We get the url for our local web file. Bundle.main.url will return an optional URL so we need to unwrap it. If you need to get the URL from a subdirectory, you can use the subdirectory argument, I have provided an example below.
  2. Once we have the local web file URL we can use the loadFileURL method on WKWebView to load the file from the url that we pass to it. We pass the same url to allowReadAccessTo. This argument will allow the web view to only open that specific file. If we passed a directory as an argument, the web view would only be able to load a file within that directory.

Subdirectory example code

if let indexURL = Bundle.main.url(forResource: "index",
                                  withExtension: "html",
                                  subdirectory: "myWebsiteContent") {
    self.webView.loadFileURL(indexURL,
                             allowingReadAccessTo: indexURL)
}

If I build and run my project now, I see this:

Nothing too special, but that is all that I have in my html:

<!DOCTYPE html>

<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <div class="hello-webview">
            HTML with styling
        </div>
    </body>
</html>

Source

Github

HTML/CSS