0

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

7
  • This might help: stackoverflow.com/a/53133740/4490923 Commented Jun 4, 2022 at 21:10
  • Thanks! I did try that but the output is the same, I just get the HTML loaded on the simulator but the JS File is not being executed ): Commented Jun 4, 2022 at 21:26
  • Did you try with deletingLastPathComponent in your url? Commented Jun 4, 2022 at 21:29
  • Yeah, I did but no luck either, I'm not sure if I'm doing something wrong Commented Jun 4, 2022 at 21:42
  • Can you share the two files on drive so I can test them on my side? Commented Jun 4, 2022 at 21:45

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.