Inject JavaScript into WKWebView

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.

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

class MyWebViewViewController: UIViewController, WKNavigationDelegate, WKUIDelegate, WKScriptMessageHandler {
    
    
    
    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://www.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 ""
        }
    }
    
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        
    }
}

For more Swift code examples and tutorials, please check the Swift Code Examples page on this website.


Leave a Reply

Your email address will not be published.