Implementing a bi-directional communication between C# and Javascript in Xamarin.iOS

  • August 8, 2019
  • 0
99xtechnology

Shalitha Suranga

Software Engineer
Apache committer and PMC member | Open source developer

Xamarin is a cross-platform mobile application development framework which uses .NET ecosystem. The key advantages of Xamarin are,

– Ability to create fully native user interfaces, as well as a cross-platform UI toolkit called Xamarin.Forms

– Application logic can be reused by making a shared .NET project.

– There are C# class mappings for all native components and required classes of Android and iOS.


Webview components in iOS

There are two webview components in iOS, UIWebView and WKWebView. The first one is now deprecated (Starting in iOS 8.0 and OS X 10.10 Apple recommends not to use UIWebView). Therefore, we are able to use WKWebView in order to display rich HTML content inside our iOS applications.


Bi-directional communication

There are situations that developers need to invoke native code from Javascript and vice versa. In other words, it is like implementing a bridge between native code and web scripts. 



Getting started with WkWebview sample project

It is possible to load web content to web view from a string, remote URL and local file path. We will be using content from a local file in this tutorial. Thus, our goal is to display a text message in webview via a native button and display a text message in native via a button which resides inside the web view. (See the figure below)

 

At the top of the screen, there is a webview which has rendered version of index.html file. The HTML file defines invokeWeb function which will be triggered from native ‘Invoke Web’ button. ‘Invoke Native’ HTML button calls InvokeNative function which triggers a native function.

Resources/www/index.html source

ViewController.cs source




Source code explanation

C# to Javascript communication

When the native button is clicked it will execute this code snippet

 

webView.EvaluateJavaScript("invokeWeb('Hello!')", null);

Thereafter, invokeWeb Javascript function will be executed and <span> tag will display Hello! String as expected.

Javascript to C# communication

At ViewDidLoad following code snippet will be executed

 

webView.Configuration.UserContentController.AddScriptMessageHandler(new MessageHandler(this), "native");

Thereafter MessageHandler will be listening to Javascript method invocations which are coming from window.webkit.messageHandlers.native

invokeNative wrapper method is injected to WkWebView’s document by using the following code since we need to use invokeNative globally.

 

webView.Configuration.UserContentController.AddUserScript(
  new WKUserScript(
    new NSString("window.invokeNative=function (param) {window.webkit.messageHandlers.native.postMessage(param);}"),
WKUserScriptInjectionTime.AtDocumentStart, false));

Eventually, when ‘Invoke Native’ button clicked it will trigger DidReceiveScriptMessage of MessageHandler. Importantly, it has ‘Hello!’ as the string parameter. Thereafter ctx.ChangeTextAsync is invoked and lbl native label is updated with ‘Hello!’ as Text.


Conclusion

If the requirement is to expose multiple native functions to the window object the function/action name can be passed via wrapper function and native function selection logic can be implemented inside DidReceiveScriptMessage of the MessageHandler.

Download tutorial   https://github.com/shalithasuranga/xamarin-ios-jsnative-com

 

Find Shalitha Suranga on Medium for more tutorials and articles

Add comment

Your email address will not be published. Required fields are marked *