Loading local HTML with local Javascript Sources in a WKWebView (iOS, Swift)-ThrowExceptions

Exception or error:

I am trying to load a local html file in a WKWebView for a iOS app (Swift 4.2). Unfortunately, this local file contains javascript code that does not seem to be executed.

Below is this html file (taken from https://www.verovio.org/tutorial.xhtml?id=topic00):

<html>
    <head>
        <title>Verovio Hello World! example</title>
        <script src="verovio-toolkit.js" type="text/javascript" ></script>
        <script src="jquery-3.1.1.min.js" type="text/javascript" ></script>
    </head>
    <body>
        Hello World!
        <div id="svg_output"/>
        <script type="text/javascript">
            var vrvToolkit = new verovio.toolkit();
            $.ajax({
               url: "Beethoven_StringQuartet_op.18_no.2.mei"
               , dataType: "text"
               , success: function(data) {
               var svg = vrvToolkit.renderData(data);
               $("#svg_output").html(svg);
               }
               });
        </script>
    </body>
</html>

And below the view controller file written in swift:

import UIKit
import WebKit

class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {

    @IBOutlet weak var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        webView.uiDelegate = self
        webView.navigationDelegate = self

        let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "html")!
        webView.loadFileURL(url, allowingReadAccessTo: url)
    }
}

Files are local under “Build Phases/Copy Bundle Resources” in the project properties. I also tried to put them in a directory but without any success. Below the file organization inside the project.

enter image description here

EDIT: When I change the url in the html file from Beethoven.mei to https://www.verovio.org/gh-tutorial/mei/Beethoven_StringQuartet_op.18_no.2.mei (same file but on Verovio’s website), anything works good!!

So:

  • Local .js resources work fine

  • The issue comes from jquery not able to load local text file

Any idea on how to make jquery able to load the local file?

Thank you!

M.

How to solve:

First check your index.html file has scr path for js. if like below, that means js files contain in js folder. so you need to add reference to that folder while add to project.

<script src="js/jquery.js"></script>

then get the main resource path like below

let path = Bundle.main.resourcePath! + "/\(folderName)/\(fileName)"
print("path:=",path )

after that load that file to webView

do {
    let contents =  try String(contentsOfFile: path, encoding: .utf8)
    let baseUrl = URL(fileURLWithPath: path)
    webView.loadHTMLString(contents as String, baseURL: baseUrl)
} catch {
    print ("File HTML error")
}

###

According to the docs, loadFileURL does this:

If readAccessURL references a single file, only that file may be loaded by WebKit. If readAccessURL references a directory, files inside that file may be loaded by WebKit.

The url you got is a url of a file, namely the HTML file. You need the url of the directory. You can do this by calling deletingLastPathComponent:

webView.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())

###

You can use the loadHTMLString method to load the HTML, as below:

let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "html")!
do {
    let html = try String(contentsOf: url)
    webView.loadHTMLString(html, baseURL: url.deletingLastPathComponent())
} catch ....

The baseURL point to your app directory in file system. You can write in the src property of the script tag relative location that is interpreted as relative to baseURL.

Leave a Reply

Your email address will not be published. Required fields are marked *