Forum Xamarin.Forms

Execute Javascript in WebView

Veto91Veto91 Member ✭✭

Hello,

im trying to execute Javascript in my Xamarin.Forms WebView by using the tutorial described here:

https://www.xamarinhelp.com/xamarin-forms-webview-executing-javascript/

Android works really good but I have problems setting this up on iOS. In the iOS custom renderer I basically return the js execute result by

return Task.FromResult(this.EvaluateJavascript(js));

Since last year the iOS api changed and this line throws an error when debugging. It turns out that I should use WkWebViewRenderer instead of WebViewRenderer. I tried to change but EvaluateJavascript() method now wants two arguments... one is the js string and one is a WKJavascriptEvaluationResult handler ...

I dont know how to adapt the code in the tutorial... can someone help?

Best Answer

  • Veto91Veto91 Member ✭✭
    Accepted Answer

    I just changed

    return Task.FromResult(this.EvaluateJavascript(js));

    to:

    var x = await webView.EvaluateJavascriptAsync(js);
    return x;
    

    and now it works.

Answers

  • JarvanJarvan Member, Xamarin Team Xamurai

    Starting in April 2020, Apple will reject apps that still use the deprecated UIWebView API. To execute Javascript in WKWebView in ios. Try to create a WKUserScript object to inject the invokeCSharpAction JavaScript function into the web page.

    Check the code:

    [assembly: ExportRenderer(typeof(Custom), typeof(CustomWebViewRenderer))]
    namespace CustomRenderer.iOS
    {
        public class CustomWebViewRenderer : WkWebViewRenderer, IWKScriptMessageHandler
        {
            const string JavaScriptFunction = "function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}";
            WKUserContentController userController;
    
            public HybridWebViewRenderer() : this(new WKWebViewConfiguration())
            {
            }
            public HybridWebViewRenderer(WKWebViewConfiguration config) : base(config)
            {
                userController = config.UserContentController;
                var script = new WKUserScript(new NSString(JavaScriptFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
                userController.AddUserScript(script);
                userController.AddScriptMessageHandler(this, "invokeAction");
            }
    
            protected override void OnElementChanged(VisualElementChangedEventArgs e)
            {
                base.OnElementChanged(e);
                ...
            }
    
            public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
            {
                ((HybridWebView)Element).InvokeAction(message.Body.ToString());
            }
            ...
        }
    }
    

    Tutorial:
    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/hybridwebview#invoke-c-from-javascript

  • Veto91Veto91 Member ✭✭

    So basically I have to do everything new on both platforms and cannot just adapt my iOS part?

  • Veto91Veto91 Member ✭✭
    Accepted Answer

    I just changed

    return Task.FromResult(this.EvaluateJavascript(js));

    to:

    var x = await webView.EvaluateJavascriptAsync(js);
    return x;
    

    and now it works.

Sign In or Register to comment.