In Swift, it is possible to inject a JavaScript code into a WKWebView and execute it from your app. The below code example demonstrates how to:
- Load HTML file from a local file,
- Load JavaScript code from a local file,
- Create WKUserScript object,
- Inject JavaScript into an HTML document.
If you are interested in video lessons on how to write Unit tests and UI tests to test your Swift mobile app, check out this page: Unit Testing Swift Mobile App
Load HTML File From App Bundle
let myProjectBundle:Bundle = Bundle.main let myUrl = myProjectBundle.url(forResource: "my-html-file", withExtension: "html")! myWebView.loadFileURL(myUrl,allowingReadAccessTo: myUrl)
Load JavaScript Code From a Local File
The below code example is a function which you can add to your Swift file and call to load the content of a demo-script.js file.
func getMyJavaScript() -> String { if let filepath = Bundle.main.path(forResource: "demo-script", ofType: "js") { do { return try String(contentsOfFile: filepath) } catch { return "" } } else { return "" } }
where:
demo-script – is the name of a file. Notice that there is no need to specify file extension here.
js – The demo-script file extension.
Inject JavaScript to WKWebView with WKUserScript
var myWebView: WKWebView! override func viewDidLoad() { super.viewDidLoad() let config = WKWebViewConfiguration() let js = getMyJavaScript() let script = WKUserScript(source: js, injectionTime: .atDocumentEnd, forMainFrameOnly: false) config.userContentController.addUserScript(script) config.userContentController.add(self, name: "clickListener") myWebView = WKWebView(frame: view.bounds, configuration: config) myWebView.uiDelegate = self myWebView.navigationDelegate = self view.addSubview(myWebView!) }
where:
getMyJavaScript() – is a function that loads JavaScript from a local file. The source code of this function is also on this page.
Complete Example
import UIKit import WebKit import Firebase class MyWebViewViewController: UIViewController, WKNavigationDelegate, WKUIDelegate { var myWebView: WKWebView! override func viewDidLoad() { super.viewDidLoad() let config = WKWebViewConfiguration() let js = getMyJavaScript() let script = WKUserScript(source: js, injectionTime: .atDocumentEnd, forMainFrameOnly: false) config.userContentController.addUserScript(script) config.userContentController.add(self, name: "clickListener") myWebView = WKWebView(frame: view.bounds, configuration: config) myWebView.uiDelegate = self myWebView.navigationDelegate = self view.addSubview(myWebView!) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let myProjectBundle:Bundle = Bundle.main let myUrl = myProjectBundle.url(forResource: "my-html-file", withExtension: "html")! myWebView.loadFileURL(myUrl,allowingReadAccessTo: myUrl) //let url = URL(string: "https://appsdeveloperblog.com")! //myWebView.load(URLRequest(url: url)) } func getMyJavaScript() -> String { if let filepath = Bundle.main.path(forResource: "demo-script", ofType: "js") { do { return try String(contentsOfFile: filepath) } catch { return "" } } else { return "" } } }