Communication between Xamarin.Forms application and WebView

In this post we will take a closer look at WebView in Xamarin.Forms and communication between web page in WebView and Xamarin.Forms mobile application. In many applications we have to render web page or html content to display login page, Paypal credit card form or purchase details. When we render page, the following problem usually appears:

  • Post loading scripts still work after page is loaded.
  • Binding mobile application action to page event.
  • Binding page action to mobile application event.
  • Rendering html content from file.

Fortunately we can do all of this with XLabs.Forms – library with powerful cross platform set of controls. In this post I will show you only HybridWebView, but I strongly encourage you to check other library controls. In my example I will add WebView with content from krystianczaplicki.com/webview and establish communication on both sides.

At the beginning we have to create new Xamarin.Forms project called XamarinFormsWebViewSample and add XLabs.Forms, XLabs.Core, XLabs.Platform, XLabs.Serialization, XLabs.Serialization.JSON nugets to all projects.

After adding nugget packages Packages folder should look like this.

Now it’s time to check code of krystianczaplicki.com/webview web page.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="bootstrap.min.css" />
    <title>Login Form</title>
  </head>
  <body>
    <div class="container">
      <h1>Login Form</h1>
      <div id="loginAlert"></div>
      <form>
        <div class="form-group">
          <label for="username">Username</label>
          <input type="text" class="form-control" id="username" placeholder="Enter username" />
        </div>
        <div class="form-group">
          <label for="password">Password</label>
          <input type="password" class="form-control" id="password" placeholder="Password" />
        </div>
        <input type="button" class="btn btn-primary" onclick="login()" value="Login" />
      </form>
    </div>
    <script src="jquery-3.2.1.slim.min.js"></script>
    <script src="bootstrap.min.js"></script>
    <script>
        function displayLoginAlert(status) {
            var alert = status == 'True' ? 
                '<div class="alert alert-success">You have been successfully logged in.</div>' :
                '<div class="alert alert-danger">Username or password is incorrect.</div>';

            $("#loginAlert").html(alert);
        }

        function login() {
            var username = $("#username").val();
            var password = $("#password").val();

            Native("login", {
                username: username, 
                password: password
            });

            $("#username").val('');
            $("#password").val('');
        }
    </script>
  </body>
</html>

On the web page we have login form with username and password, we can submit form by clicking on Login button. We also have javascript functions to communicate between web page and mobile application. First function is called displayLoginAlert and we will call it from our mobile application after user authentication with status equals to ‘True’ if user is correct, otherwise ‘False’, then it will display alert box with message. Second function is login, in this function we will call Native with parameters “login” which is name of callback and object with username and password. Our mobile application will receive callback and try to authenticate user.

This is how the web page looks in the browser.

Once we know everything about the web page that we will be displayed in the mobile application, we can add WebView. To do this we will add HybridWebView in XamarinFormsWebViewSamplePage code behind and register login callback.

public partial class XamarinFormsWebViewSamplePage : ContentPage
{
    private const string WebViewUrl = "http://krystianczaplicki.com/webview/";
    private const string LoginCallback = "login";
    private const string DisplayLoginAlertFunctioName = "displayLoginAlert";
    private const string Username = "User";

    public XamarinFormsWebViewSamplePage()
    {
        InitializeComponent();

        var serializer = new JsonSerializer();
        var webView = new HybridWebView(serializer)
        {
            VerticalOptions = LayoutOptions.FillAndExpand,
            Margin = new Thickness(20, 30),
            Uri = new Uri(WebViewUrl)
        };

        webView.RegisterCallback(LoginCallback, (arg) =>
        {
            var loginForm = serializer.Deserialize<LoginFormDto>(arg);
            var result = loginForm.Username == Username;
            webView.CallJsFunction(DisplayLoginAlertFunctioName, new[] { result.ToString() });
        });

        Content = webView;
    }
}

If we don’t use XLabs.IoC with registered serializer we have to pass serializer in constructor, so we can’t use XAML to add HybridWebView. We also set HybridWebView Uri to krystianczaplicki.com/webview and registered callback with login name where we deserialize login form data. Then we call javascript function called displayLoginAlert with boolean parameter set to true if username is equals to ‘User’, otherwise false.

We must also add LoginFormDto to deserialize login data from web page.

public class LoginFormDto
{
    public string Username { get; set; }
    public string Password { get; set; }
}

In iOS project we have to create instance of HybridWebViewRenderer method FinishedLaunching in AppDelegate after LoadApplication.

var hybridRenderer = new HybridWebViewRenderer();

One last thing to do is set ATS in the iOS project to allow rendering krystianczaplicki.com/webview in WebView. Open Info.plist and add this structure.

Now we can run mobile application and after loading web page we should have the following view. When we click on the Login button alert should appear.

Sometimes when we have to render web page content inside mobile application we can face problems with loading scripts or we need to set up communication between web page and mobile application. Then we can use XLabs.Forms, which has extended controls that make it easier. In this post I have only presented the basics of communication between Xamarin.Forms application and web page but XLabs.Forms also allows you to load your own scripts, load html content from file and much more. I strongly encourage you to check other HybridWebView capabilities and controls from XLabs.Forms. Source code for this example is on github.

Do you have any experience with WebView? If so, share your insights on this subject in a comment!