5

I am sorry, if this question was already asked, but all the answers I could find are for complicated solutions.

I have a viewController, which is webView. I added WKWebView, to my view from WebKit library, and opened simple url. Inside of my ViewController, I have a native function called showAd. When the user press the button, which was implemented in javascript, it show call showRewardsAd. I set the break point to the userContentController, however, it never goes there.

func showAd(){
   print("invoked")
}
extension WFWebViewController: WKScriptMessageHandler{
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "showRewardsAd"{
            self.showRewards()
            webView.evaluateJavaScript("test", completionHandler: nil)
        }
    }
}

My goal is to simply allow this function to be called from javascript part. As I know, if I want to call javascript function in swift, I simply have to say:

 webview.addJavascriptInterface('javascript: function_name();')

However, in my case, I want to do it in reverse order. Call swift function in Javascript code.

1 Answer 1

4

You need to inject your user script inside the webView so you could listen to JavaScript's messages when they are posted.

Firstly, you will need to initialize the webView's config and preferences, to allow javaScript:

let config = WKWebViewConfiguration()
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
config.preferences = preferences

Now, you need to inject your script to listen for the click events from the webView:

let userController = WKUserContentController()
let javaScript = "showRewardsAd = function() {\n" + "window.webkit.messageHandlers.adClicked.postMessage(); }"
let script = WKUserScript(source: javaScript, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
userController.addUserScript(script)
userController.add(self, name: "adClicked")
config.userContentController = userController

Now instantiate your webView with the configuration from above:

self.webView = WKWebView(frame: .zero, configuration: config)

Now, your WKScriptMessageHandler protocol is implemented correctly:

extension WFWebViewController: WKScriptMessageHandler{
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "showRewardsAd"{
            self.showRewards()
            print("Ad is being shown.")
        }
    }
}

I hope this works for you. I assumed that showRewardsAd is implemented in the JavaScript on the website which you're accessing.

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.