Home > Blockchain >  WebView load external HTML with linked JS File - Swift
WebView load external HTML with linked JS File - Swift

Time:06-05

I am trying to create a WebView that displays a local HTML file index.html, this HTML File has a linked JS External File form.js, I created both of these using VSCode and everything works just fine when running it with Live Server. But when building and running the app on XCode the HTML File seems to work just fine, but I don't get the alert nor the print statement defined in the JS File. Here's the code I'm running:

Swift Code:

private func loadRequest() {
    let htmlPath = Bundle.main.path(forResource: "index", ofType: "html")
    guard let htmlPath = htmlPath else { return }
    let url = URL(fileURLWithPath: htmlPath)
    let request = URLRequest(url: url)
    webView.load(request)
}

HTML File:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Form</title>
</head>
<body>
    <form>
        <div>
            <label>Name</label>
            <input>
        </div>
        <div>
            <label>Last Name</label>
            <input>
        </div>
        <div>
            <label>Date of birth</label>
            <input type="date" id="birthday" name="birthday">
        </div>
        <div>
            <button>Button1</button>
            <input>
        </div>
        <div>
            <button>Button2</button>
            <input>
        </div>
    </form>
    <script src="form.js"></script>
</body>
</html>

JS File

alert('test');
console.log("This is workig");

I already imported both these files to my XCode Project, which are located in the Main folder of the app. So I'm not sure what I'm doing wrong, this is the first time I try building something like this. Please, can anyone help me? I've been looking everywhere for a solution but I am not really familiar with HTML/JS code. Thanks in advance! (:

enter image description here

CodePudding user response:

You can feed the webView with JavaScript code, however, WKWebView doesn't recognize JavaScript's 'alert' function. Here's a possible workaround it:

1- Inject the script into webView

2- Use webView's runJavaScriptAlertPanelWithMessage method to receive the alert message

3- Display the alert's message

Here is the code I used to test your index.html and form.js files:

enter image description here


import UIKit
import WebKit

class ViewController: UIViewController {

    var webView: WKWebView!
    
    var bundle: Bundle {
        return Bundle.main
    }

    var scriptString: String {
        if let path = bundle.path(forResource: "form", ofType: "js") {
            do {
                return try String(contentsOfFile: path)
            } catch {
                return ""
            }
        } else {
            return ""
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let config = WKWebViewConfiguration()
        let js = scriptString
        let script = WKUserScript(source: js, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
        
        config.userContentController.addUserScript(script)
        config.userContentController.add(self, name: "alert")
        
        webView = WKWebView(frame: view.bounds, configuration: config)
        webView.uiDelegate = self
        webView.navigationDelegate = self
        
        view.addSubview(webView)
        
        NSLayoutConstraint.activate([
            webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            webView.topAnchor.constraint(equalTo: view.topAnchor),
            webView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
        
        
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        loadRequest()
        
    }
    
    private func loadRequest() {
        guard let url = bundle.url(forResource: "index", withExtension: "html") else { return }
        webView.loadFileURL(url, allowingReadAccessTo: url)
                
    }

}

extension ViewController: WKScriptMessageHandler, WKUIDelegate, WKNavigationDelegate {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {

    }
    
    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo) async {
        
        let alert = UIAlertController(title: "Alert", message: message, preferredStyle: .alert)
        let action = UIAlertAction(title: "Ok", style: .default) { ac in
            // Do something
        }
        alert.addAction(action)
        present(alert, animated: true, completion: nil)
    }
}

Output:

enter image description here

More info:

WKUserScript not working

iOS WKWebView not showing javascript alert() dialog

  • Related