WebView in Xamarin.Forms..
Unfortunately this cannot be done by default in WebView.
Behold, Hybrid WebView!
Well that’s a very simplistic explanation, but there’s a whole article about it on Microsoft Xamarin Docs, Customizing a WebView if you’re interested! Since its already there, I wouldn’t be going into complete details of it, rather I would be explaining the improved implementation I have done on top of it for the Hybrid WebView.
In order to do this, in par with Xamarin.Forms WebView, we need to implement a Custom Renderer for WebView, which we will refer to as HybridWebView.
Let the coding begin!
We’re going to build native renderers for each platform we’re targeting, Android, iOS, and UWP (Windows). Basically all the renderers follow the same basic concept as we discussed before, but each of their implementation is going to be different based on the platform.
We need to make sure to handle the subscribe and unsubscribe of the Element Native properties and events properly in the renderer’s OnElementChanged() event.
Alright now let’s get into details of each native renderer.
We’re going to use the Android’s WebViewRenderer to subclass our HyrbidWebViewRenderer.
Like we discussed before for Android, we have the following script injection defined,
Both those custom objects need to be set up in the HybridWebView in the renderer Element upon instantiation.
Once all that set up, and you build the Android project straight away, you might be getting a build error as following. (unless you’ve set this fix up before in your project)
Its caused by the JsBridge class we implemented with an Export attribute for the invokeAction method for our renderer, to export this into a native java method. So we need to add the Mono Android Export library.
You can fix this by going to Android Project -> References -> Add References -> Select Assemblies tab on the left panel -> tick on Mono.Android.Export Reference from the list of References.
Click Ok and rebuild, you’re all set! 😉
That’s pretty much it for the Android Renderer. Next on to iOS…
Then for iOS, we have the following script injection defined using webkit API, accessing the invokeAction script that we attached and finally calling on the postMessage() method with the data parameter.
IWKScriptMessageHandler provides us with DidReceiveScriptMessage() method which we use to transfer the data up to the Xamarin.Forms level handler using, HybridWebView.InvokeAction(data).
Quite simple ans straight forward eh! next to Windows, or UWP as you might prefer.. 😉
We use the Xamarin native WebViewRenderer for UWP or Windows platform.
The native default renderer grants us access to these two events NavigationCompleted and ScriptNotify. We need to make sure to subscribe to those events in our HybridWebViewRenderer in Windows as follows.
And then ScriptNotify, provides us the chance to redirect back the execution to Xamarin.Forms level handler using HybridWebView.InvokeAction(data).
Bingo, that completes the UWP or Windows Renderer!
Now that we’ve finished the setting up of our HybridWebView and its Native Renderer for Android, iOS and Windows, its time to consume it and taste it out! 😉
Let’s try it out!
Here’s we shall begin by consuming it in a XAML page in Xamarin.Forms!
I’m just going to use the Main UI Thread’s help to execute any UI related stuff. And here’s a little demo HTML that I’m setting up in our Hyrbid WebView.
So let’s try out that sample code bits in action!
Time for some action! 😉
Hit that F5 yo! (well.. if you’re in Visual Studio! lol)
Side by side iOS, Android and UWP working like charm! 😉
Here we are typing some text in the Xamarin.Forms Entry element and sending it into the HTML inside the WebView. And then typing some text in the HTML Text Input element inside the WebView and click on HTML Button, and sending it to the Xamarin.Forms Label to be displayed, works like a charm!
I have shared the demo app code in my github as usual: github.com/XFWebViewInteropDemo
Yeah just a fun little demo I have added to the same repo in github! 😀
Yep it’s that time, for some extra tips based on my experience with Xamarin.Forms Hybrid WebView! Although the extra tips that I already discussed in my previous article Talking to your WebView in Xamarin.Forms! still applies for this as well since we’re still extending from default Xamarin.Forms WebView, but apart from that…
Web Source, Embedded, Code HTML!? all same!
Doesn’t matter whatever the source of the HTML you’re setting in the Hybrid WebView, be it a web source directly from a URL, or loading an embedded HTML File, or even a code generated dynamic HTML content, it doesn’t make a difference.
The only thing that matters is the invokeCSharpAction() in your rendered HTML, so that the native renderers can pick it up and forward the execution to Xamarin.Forms .NET handlers!
Yes! extra parameters!
HybridWebView.InvokeAction(string data1, string data2)
var dataBody = data; var dataArray = dataBody.Split("|"); var data1 = dataArray; var data2 = dataArray; ((HybridWebView)Element).InvokeAction(data1, data2);
Finally wire it all up, you’re good to go! 😉 I might share another article with some cool implementation with this in near future! 😀
Well that’s pretty much it!
Share the love! Cheers! 😀