Category Archives: Mobile App Development

Building a bi-directional interop bridge with WebView in Xamarin.Forms!

Let’s build an advanced communication bridge into your Xamarin.Forms WebView, talk to it, and let it talk back to us at will!? 😉 lol Yes let me show you how to pass data from Javascript environment to C# .NET run time in the Web page rendered inside your Xamarin.Forms WebView!

I’m talking about building a bi-directional communication tunnel with HTML/Javascript inside your WebView in Xamarin.Forms yo! 😀 buckle up your seatbelts!

So in my previous article, Talking to your WebView in Xamarin.Forms! I talked about, how to build a uni-directional C# .NET to Javascript environment in Xamarin.Forms WebView.

WebView in Xamarin.Forms..

In this article I’m going to take another step forward and allow the same functionality to occur the other way around as well… We’re talking about a two-way invoking between .NET run time and javascript run time in a Xamarin.Forms WebView!

Unfortunately this cannot be done by default in WebView.

Behold, Hybrid WebView!

This right here is a bit more advanced extension of the WebView with a bit of Xamarin Native magic! 😉 In order to establish an invoke bridge directly from HTML Javascript sandbox that its running inside the WebView, out to the .NET runtime, we need something more natively handled in Xamarin!

Basically we’re going to implement a device native script handler for the WebView which is going to handle the bridging between the Javascript and the .NET runtime handshake, in return giving us the opportunity to invoke calls from javascript into the .NET run time the Xamarin.Forms is execution on! 😉

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.

Over there it focuses on loading Embedded HTML content, but I will extend my implementation to support for dynamic HTML content, allowing you to handle javascript loaded from a Web Source and support even run time generated javascript.

Invoking C# from Javascript in the 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.

HybridWebViewRenderer will be created across all the native platforms we intend to use our HybridWebView, in Android, iOS and Windows native environments each equipped with its own javascript handler to build a bridge on to our .NET run-time. 😉

We access the native WebViewRenderer properties and basically implement a special handler to listen to a certain pre-defined Javascript method execution. In this method which we add into the javascript that is rendered inside the WebView, we will define the parameters we need to use, in that way we can pass any number of parameters and data types as we want.

We’re going to intercept the execution of this javascript method inside our Hybrid WebViewRender, and then redirect it on to the .NET method we’ve subscribed to. So in the Hybrid WebView definition we will have an Action method that we bind to in our Xamarin.Forms level which we will subscribe to wherever we’re using this magical bits! 😉

Let the coding begin!

Let’s begin with HybridWebView Control in Xamarin.Forms! Here we;re adding an Action that we will subscribe to in order to receive data from Javascript invokes inside the WebView rendered content.

HybridWebView

namespace XFWebViewInteropDemo.Controls
{
    public class HybridWebView : WebView
    {
        private Action<string> _action;

        public void RegisterAction(Action<string> callback)
        {
            _action = callback;
        }

        public void Cleanup()
        {
            _action = null;
        }

        public void InvokeAction(string data)
        {
            if (_action == null || data == null)
            {
                return;
            }
            _action.Invoke(data);
        }
    }
}

 

InvokeAction is the method that will be used by the Native Renderer object to direct the invokes from javascript executions. Using the RegisterAction we can dynamically register the Action we need to subscribe to.  You can add any number of parameters as you wish in here, but you need to make sure to handle them in the native renderer as well.

Native Renderers…

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.

We’re going to inject the javascript method that we’re going to listen to in the renderers as following.

private const string JavaScriptFunction = "function invokeCSharpAction(data){....}";

 

We will be defining this in each renderer, according to the native platform, and you can define the number of parameters you want to pass from this method as you wish. Right now we’re using a single parameter as you can see.  Every time a invokeCSharpAction() javascript method executes inside the WebView, it will get fetched by the Renderer and the following method call will occur.

((HybridWebView)Element).InvokeAction(value);

 

Up to the HybridWebView’s Action subscription on Xamarin.Froms run time, allowing our Action to fire up and retrieve the data coming in from javascript.

Alright now let’s get into details of each native renderer.

Android Renderer!

We’re going to use the Android’s WebViewRenderer to subclass our HyrbidWebViewRenderer.

github: /XFWebViewInteropDemo.Android/Renderers/HybridWebViewRenderer.cs

Like we discussed before for Android, we have the following script injection defined,

private const string JavascriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";

 

For Android we need some extra bits of implementation, by creating a JavascriptWebViewClient that will set up listening to the execution of javascripts inside the WebView.

Then we have to create a JsBridge, which handles the interfacing with Javascripts, and fires up InvokeAction() method to redirect the execution flow up to the Xamarin.Forms level handlers.

Both those custom objects need to be set up in the HybridWebView in the renderer Element upon instantiation.

Control.SetWebViewClient
(new JavascriptWebViewClient($"javascript: {JavascriptFunction}"));
Control.AddJavascriptInterface
(new JsBridge(this), "jsBridge");

 

That’s pretty much it for the Android Renderer. Next on to iOS…

iOS Renderer!

For iOS we are going to use WkWebViewRenderer as the base renderer for our HybridWebView and in addition we have to implement IWKScriptMessageHandlder interface to handle the custom javascript execution monitoring that we target to handle.

github: /XFWebViewInteropDemo.iOS/Renderers/HybridWebViewRenderer.cs

We set up a WKWebViewConfiguration object in the constructor and we get access to the property WKWebViewConfiguration.UserContentController which allows us to set up our native bridge to Javascript execution firing up inside the WebView.

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");
}

 

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 parameters.

private const string JavaScriptFunction = "function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}";

 

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.. 😉

UWP Renderer!

We use the Xamarin native WebViewRenderer for UWP or Windows platform.

github: /XFWebViewInteropDemo.UWP/Renderers/HybridWebViewRenderer.cs

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.

Control.NavigationCompleted += OnWebViewNavigationCompleted;
Control.ScriptNotify += OnWebViewScriptNotify;

 

NavigationCompleted, allows is to easily inject our javascript handler function, which is defined as follows for UWP or Windows,

private const string JavaScriptFunction = "function invokeCSharpAction(data){window.external.notify(data);}";

 

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!

<controls:HybridWebView
	x:Name="webViewElement"
	HorizontalOptions="FillAndExpand"
	VerticalOptions="FillAndExpand" />

github: /XFWebViewInteropDemo/HybridWebViewDemoPage.xaml

And then don’t forget to Subscribe to retrieve the data coming in from javascript inside our WebView using RegisterAction() method we created!

...
    // Subscribe for the data coming in from Javascript
    webViewElement.RegisterAction(DisplayDataFromJavascript);
}

private void DisplayDataFromJavascript(string data)
{
    Device.InvokeOnMainThreadAsync(() =>
    {
        ...
        // Do whatever you want with the data
        ...
    });
}
...

github: /XFWebViewInteropDemo/HybridWebViewDemoPage.xaml.cs

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.

webViewElement.Source = new HtmlWebViewSource()
{
    Html =
        $@"<html>" +
        "<head>" +
            ...
            "<script type=\"text/javascript\">" +
                "function invokexamarinforms(){" +
                "    try{" +
                "        var inputvalue = 
document.getElementById(\"textInputElement\").value;" +
                "        invokeCSharpAction(inputvalue + '. This is from Javascript in the WebView!');" +
                "    }" +
                "    catch(err){" +
                "        alert(err);" +
                "    }" +
                "}" +
            "</script>" +
            ...
        "</head>" +

        "<body>" +
            "<div>" +
                "<input type=\"text\" id=\"textInputElement\" placeholder=\"type something here...\">" +
                "<button type=\"button\" onclick=\"invokexamarinforms()\">Send to Xamarin.Forms</button>" +
            "</div>" +
        "</body>" +

        "</html>"
};

github: /XFWebViewInteropDemo/HybridWebViewDemoPage.xaml.cs

As you can see I have a javascript function, invokexamarinforms() that will get invoked from a button call in the body. Once this method executes, it calls on the invokeCSharpAction() method that we defined in our Hybrid WebViews Native renderers.

In my javascript snippet I’m surrounding this call with a try catch in order to make sure the Native Renderer is properly implemented or not. Making sure this method is properly executes is a crucial step during debug if you run into any issues.

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! 😉

As you can see in my simple Xamarin.Forms demo, I am demonstrating a simple C# .NET to Javascript call with data and Javascript to C# .NET call with data, a true bi-directional communication bridge!

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

Extra tips!

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!

Even though I’m showcasing only a single parameter during this demo article, from javascript to C# .NET run time, you can easily extend this same implementation to pass any number of parameters as you wish! As I explained in the article make sure to define it in the following bits,

HybridWebView.InvokeAction(string data1, string data2)
private const string JavaScriptFunction = "function invokeCSharpAction(data1, data2){....}";
((HybridWebView)Element).InvokeAction(data1, data2);

And wire it all up, you’re good to go! 😉 I might share another article with some cool implementation with this in near future! 😀

Conclusion

You can easily build a communication bridge from C# .NET to javascript environment in Xamarin.Forms WebView! but the other way is not really possible out of the box!

That’s why we’re implementing this Hybrid WebView Control which allows us build a communication bridge from javascript to C# .NET environment directly during run time! 😉

So this concludes my bi-directional communication tunnel with HTML/Javascript inside your WebView in Xamarin.Forms yo!

Well that’s pretty much it!

Share the love! Cheers! 😀

Talking to your WebView in Xamarin.Forms!

Let’s build a communication bridge into your Xamarin.Forms WebView, and talk to it!? 😉 lol Yes let me show you how to pass data into the Web page rendered inside your Xamarin.Forms WebView!

I’m talking about building a uni-directional communication with Javascript inside your WebView in Xamarin.Forms yo! 😀 get your game face on!

WebView in Xamarin.Forms..

Xamarin.Forms provides a neat WebView that could render any Web HTML content efficiently similar to a browser inside your own Xamarin.Forms App.

Earlier there used to be a lots of issues that needed to be dealt with when to comes to rendering HTML content alongside Javascript inside the WebView, but with the recent update it has gotten far better with lots of features and facilities straight out of the box to be used! 😀

Invoking Javascript in the WebView!

Using the WebView straight out of the box, we can execute Javascript methods rendered inside the HTML content. Now I know this used to require a lot hacks and tricks, along side dealing with lot of run time exceptions.

But in the most recent updates of Xamarin.Forms, the WebView has gotten rock solid, and now even provides a dedicated method, EvaluateJavaScriptAsync() to invoking Javascript methods straight out of the box.

WebView.EvaluateJavaScriptAsync(String)

 

So now you can execute Javascript methods along with data parameters from you C# code in Xamarin.Forms using the default WebView control. EvaluateJavaScriptAsync() is an async method that lets you execute javascript and even await the call to response from the invoke as well.

var result = await webView
        .EvaluateJavaScriptAsync
            ("javascriptmethod('Hello world!')");

 

All you need to do is call the javascript method you’re targeting to invoke with or without the parameters you prefer using EvaluateJavaScriptAsync() in an asynchronous manner allowing you to await for a result back from the javascript into the .NET environment itself! Yep its that simple to talk to the HTML content in your WebView now! 😀

Let’s give it a try and establish a uni-directional communication with our WebView! 😉

Let the coding begin!

Here I have prepared a small demo where I’m loading some HTML content, along with a nice little javascript bits, into my WebView using HtmlWebViewSource as follows…

webViewElement.Source = new HtmlWebViewSource()
{
    Html =
        $@"<html>" +
        "<head>" +
            ...
            "<script type=\"text/javascript\">" +
                "function updatetextonwebview(text) {" +
                "    document.getElementById
                     (\"textElement\").innerHTML = text;" +
                "}" +
            "</script>" +
            ...
        "</head>" +

        "<body>" +
        ...
        ...
        "</body>" +

        "</html>"
};

Full code on github: /XFWebViewInteropDemo/DefaultWebViewDemoPage.xaml.cs

So here in my HTML content, I have a simple Javascript method, updatetextonwebview(text) where it takes in a value and set it to an HTML text element in the body. Pretty simple and straight forward.

string result = await webViewElement
        .EvaluateJavaScriptAsync
           ($"updatetextonwebview('{textEntryElement.Text}')");

 

And then I take a Text value from an Entry Element and pass it into the updatetextonwebview() javascript method using EvaluateJavaScriptAsync() of WebView.

Alright, let’s try it out!

Hit F5!

Well if you’re on Visual Studio, just hit F5 and watch the magic!

Side by side iOS, Android and UWP with Xamarin.Forms right out of the box! 😉

As you can see in my simple Xamarin.Forms demo, I have an Entry element which I type some text into and then I click on the Button which then going to pass that text data into the WebView’s javascript method. Then inside the javascript, it takes in the data and set it to a text label in the HTML body.

I have shared the demo app code in my github as usual: github.com/XFWebViewInteropDemo

No hacks, no work arounds, no custom renders, just straight out of the box in Xamarin.Forms! Works like a charm! 😉

Extra tips!

Yep it’s that time, for some extra tips based on my experience with Xamarin.Forms WebView!

-Track invoking of Javascript

Using WebView.EvaluateJavaScriptRequested event you can track the javascript invoke calls injecting into the WebView from your .NET code, basically an monitoring mechanism of all your javascript invokes from C# which will allow you to validate them or add extra details as you prefer on demand.

-Track Navigation inside the WebView

WebView provides a whole list of events to track the navigation now, along side back and forward navigation, redirects, and even refresh events.

WebView.Navigating

This event Triggers upon the beginning of the Navigation, allowing you to cancel it on demand. This event provides a WebNavigatingEventArgs object which provides you all the details about the navigation that is about to occur, direction, url endpoint and so on.

This also provides WebNavigatingEventArgs.Cancel property which allows you to cancel that navigation on demand. So yeah a lot of cool bits you can do with it!

WebView.Navigated

This event Triggers after a Navigation completes, providing you with the same details similar to Navigating event. In addition it gives WebNavigatedEventArgs.Result property which tells you whether the navigation was success or failure.

WebView.GoBackRequested | GoForwardRequested | ReloadRequested

Now these are some simplified events thats provided by WebView, allowing you to directly hook into GoBack, GoForward and Reload events when they occur. Although they do not provide facility to cancel those events like how we get in Navigating event. Just a quick easy way to monitor those events as they occur.

-Think Creative!

Most developers miss this point, if you can send a simple text string, then you can pass anything into the WebView’s javascript. Well… in disguise of a string of course!

  • Get device native data
  • Location GPS data
  • Proximity data
  • Internet Connectivity data
  • Captured File/Image data

Those are few examples, yes even an Image captured from the device camera can easily be sent as a byte array converted into a base64 string!  Imagination is the limit yo! 😉

Conclusion

Xamarin.Forms WebView has come a long way since the early days, into a complete mature sandbox environment to render any HTML Web Content inside your Xamarin.Forms app. And it provides lots of features to communicate, pass data back and forth, and even monitor and control the navigation happens inside itself.

This article basically focuses on uni-directional execution from C# .NET code to Javascript environment, while you can still await for the results from the javascript.

But there is no direct execution from Javascript environment to C# .NET yeah? So in my next article I’ll share how to build a bi-directional execution from C# .NET code to Javascript environment with Xamarin.Forms WebView. 😉

Well that’s pretty much it!

Share the love! Cheers! 😀

Xamarin.Forms Native HttpClientHandler for HttpClient…

Let’s make sure our Xamarin.Forms apps are properly configured with Native HttpClientHandler for optimum performance and better network security..

If you’re using the HttpClient for making Web API calls outside your app, you probably using the HttpClientHandler to set up various kinds of configuration for the HttpClient instance.

Now this HttpClient and Native HttpClientHandler applies directly for both Xamarin Native and Xamarin.Forms apps…

Although in this article I’m focusing on Xamarin.Forms, the same configuration set up can be used for any Xamarin Native apps as well.  By default in Xamarin you can use either the Managed HttpClientHandler which is fully maintained by .NET mono run time or the Native HttpClientHandler that maps itself to the Native run time configuration.

Why Native HttpClientHandler?

Thanks to the awesomeness of the Xamarin and the powerful Xamarin.Forms ability to map itself efficiently to the Native device environment, provides you with this facility to use the device Native Network Layer’s configuration in your Apps as well.

  • Using the Native HttpClientHandler provides you with a lot of advantages in terms of Network Communication Layer, which maps itself completely to the native properties and behaviors.
  • It provides your App with the in built default System native Security such as Transport Layer Security, TLS 1.2 features. This is basically built in for both Android and iOS system devices by default, which then we can leverage automatically on to our Xamarin.Forms app as well during run time.
  • This gives the user a peace of mind, in terms of the security of the network communication in the app while also giving the user the free of choice to let the app inherit itself the system configured security settings.
  • Defaulting to the Native Network configuration we can make sure our app is fine tuned for Security and Performance on the device native level and you do not have to spend extra time managing those bits manually.
  • Another great advantage is not needing to manually handle device Proxy Settings, allowing your Xamarin.Forms app to communicate through the device’s default network tunnel.

Well that’s pretty much a good list of reasons to make sure to set up our Xamarin.Forms apps to use the Native HttpClientHandlers eh! 😉

So what are they?

So below are the Native HttpClientHandlers available in Xamarin run time for each Platform, which applies for Xamarin.Forms as well.

AndroidClientHandler -AndroidClientHandler is the new handler that delegates to native Java code and Android OS instead of implementing everything in managed code. This option has better performance and smaller executable size.

NSUrlSessionHandler -The NSURLSession-based handler is based on the native NSURLSession framework available in iOS 7 and newer. This options has better performance and smaller executable size, supports TLS 1.2 standard.

WinHttpHandler -WinHttpHandler is implemented as a thin wrapper on the WinHTTP interface of Windows and is only supported on Windows systems. Provides developers with more granular control over the application’s HTTP communication than the default HttpClientHandler class.

So here as you can see, using the device native HttpClientHandlers provides you with the best of performance and security for your app compared to opting to use the Managed HttpClientHandler where you have to manually handle those optimizations yourself.

Although I must make a note here, in Windows or UWP Xamarin apps the default set up is the .NET Managed HttpClientHandler because the underlying native environment is Windows itself. But opting to use WinHttpHandler provides arguably better advantage according to many documentation, and also it’s in the same .NET stack! 😉

What no to do?

So before we get into “the how?”, let’s first make sure the bits not to do in our app project!

– not use “Managed”

So when it comes to Xamarin.Forms, by default when you create your project in Visual Studio the Native project nodes Properties are set up to use the Native HttpClient Handlers already. You can see this in both Android and iOS Project settings,

  • Android project node -> Properties -> Android Options -> Click “Advanced”
  • iOS project node -> Properties -> iOS Build

Do not set it to option to “Managed” HttpClientHandler in either of those settings, which will opt you out of Native HttpClientHandler.

– not use “new HttpClientHanlder()” 

If the above Settings check success, the next thing to consider is not instantiating HttpClientHanlder on its own as below,

HttpClientHandler httpClientHandler = new HttpClientHandler();
...
// setting up httpClientHandler settings
...
...
HttpClient httpClient = new HttpClient(httpClientHandler);

 

This is something you should not do, which will override your Native project property set up regarding the HttpClientHandler, and opt your HttpClient to use Managed HttpClientHandler instead, resulting you losing all the native goodness!

Next let’s see what to do?

What to do?

Here are the things you need to make sure to do instead.

– not using HttpClientHandler!?

Consider not using HttpClientHandler at all with your HttpClient, then you’re basically good to go, as long as you have set it up in your App Project Native settings. Not a joke though! lol 😛

Just use plain HttpClient instance out of the box! but make sure to do the following as well.

– set Native HttpClientHandler!

Go to the following settings in each of your Xamarin.Forms Native project nodes,

  • Android project node -> Properties -> Android Options -> Click “Advanced”

  • iOS project node -> Properties -> iOS Build

Make sure to set the Native Android and NSUrlSessionHandler those settings, to opt to use AndroidClientHandler and iOS NSUrlSessionHandler for your HttpClientHandler by default.

Well UWP or Windows project nodes doesn’t have such settings as it by defaults use .NET Managed HttpClientHandler.

A little demo!

Now if its all good, you should be able to see the following behaviors in action,

So this is a little Xamarin.Forms demo that I prepared to demonstrate the behaviors of Native HttpClientHandlers on Android, iOS and Windows UWP.

Here I’m demonstrating the Network access (blue color access granted and red color access blocked in run time) for a list of scenarios,

Now you can see how each device Native environment handles those endpoint calls, basically only allowing access to trusted secure web endpoints in the native network tunnel to go through.

Well that was quite simple eh! but we all know the real life requirements wouldn’t be so simple, what if we need to use the HttpClientHandler in code?

Yes we need access to the Native HttpClientHandler in code!

So then let me walk you through handling an advance implementation of the native HttpClientHandler with more customization added in code! 😉 

How to? Advanced set up of Native HttpClientHandler!

Yes as you can see in the Project Settings, it doesn’t really give you much options to customize your Native HttpClientHandler settings, or even override some of its behaviors at all. In a real life scenarios you would definitely need some more access to your HttpClientHandler use in code.

Compared to the Managed .NET HttpClientHandler where you easily have access to all its properties and behaviors.

But it is crucial for us to stick to the Native HttpClientHandler, so the solution would be to implement an access to the Native HttpClientHandler in our Xamarin.Forms code.

– Under the hood!?

Thanks to the awesomeness of Xamarin we have full access to those Native HttpClientHandlers in code as well, so that we can use them as however as we like. Let’s take a look under the hood of these Native bits shall we,

Android:

iOS:

Windows:

Now you can see that all these Native Handlers are extending from either HttpClientHandler or the HttpMessageHandler,

Drilling down further into HttpClientHandler we can see that its extending itself from HttpMessageHandler.

– Using em in code!

Let’s start by using our AndroidClientHandler in code to be used with HttpClient instance.

var androidClientHandler = new AndroidClientHandler();
... 
// setting up native httpClientHandler settings
...
...
HttpClient httpClient = new HttpClient((HttpMessageHandler)androidClientHandler);

 

And for iOS with the NSUrlSessionHandler.

var iosClientHandler = new NSUrlSessionHandler();
... 
// setting up native httpClientHandler settings
...
...
HttpClient httpClient = new HttpClient((HttpMessageHandler)iosClientHandler);

 

Then for Windows or UWP, opt to our WinHttpHandler.

var uwpClientHandler = new WinHttpHandler();
... 
// setting up native httpClientHandler settings
...
...
HttpClient httpClient = new HttpClient((HttpMessageHandler)uwpClientHandler);

On Windows or UWP make sure to install nuget package: System.Net.Http.WinHttpHandler to use WinHttpHandler which is a far better native option than default HttpClientHandler.

As you can see we’re casting them to HttpMessageHandler as a common ground object, since they all inherit from that base.

Now that we’ve got access to them in code, we can access all their properties and behaviors, and even override to customize them as we wish to.

– build the bridge to Xamarin.Forms!

Since the above bits are not directly accessible from Xamarin.Forms, we need to build the bridge that will allow us to access the Native HttpClientHandler instance in Xamarin.Forms environment directly.

Since I already created a common ground instance across all the native environments with the casting to HttpMessageHandler, this is much easier. Now there are plenty of ways leverage the access to this object up towards Xamarin.Forms layer, but here I’m going to showcase rather a simple implementation.

code on github repo: XFNativeHttpClientHandler/Services/HttpClientService.cs

Here I have a simple Service implementation in Xamarin.Forms where it maintains a Singleton object of itself, which contains a HttpClient object and HttpClientHandler object.

Given the HttpClientHandler is provided, I am instantiating my HttpClient() on demand during the run time as you can see below.

private HttpClientService()
{
    HttpClient = HttpClientHandler != null ?
        new HttpClient((HttpMessageHandler)HttpClientHandler) 
      : new HttpClient();
}

public static HttpClientService Instance
{
    get
    {
        lock (Padlock)
        {
            return _instance ?? 
                  (_instance = new HttpClientService());
        }
    }
}

 

So the setting up of the HttpClientHandler property happens in the each Native level’s execution start up point.

On Android: MainActivity.cs

protected override void OnCreate(Bundle savedInstanceState)
{
    ...
    
    var androidClientHandler = new HttpClientHandler();
    Services.HttpClientService.HttpClientHandler =               
                                     androidClientHandler;
    
    ...
}

 

On iOS: AppDelegate.cs

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    ...
    
    var iosClientHandler = new NSUrlSessionHandler();
    Services.HttpClientService.HttpClientHandler = iosClientHandler;

    ...
}

 

On Windows (UWP): MainPage.xaml.cs

public MainPage()
{
    ...

    var uwpClientHandler = new WinHttpHandler();
    Services.HttpClientService.HttpClientHandler = uwpClientHandler;

    ...
}

 

That’s it for the set up, then let’s use it in Xamarin.Forms code:

var result = await HttpClientService.Instance.
		HttpClient.GetAsync("https://google.com/");

 

Now this should provide you with a Xamarin.Forms Solution allowing you to be able to access all the Properties and Behaviors of Native HttpClientHandlers!

Yay! Access in Code!

So the whole point of access these Native HttpClientHandlers in code was to be able to customize their settings and behaviors according to our requirements eh! 😀

Go ahead and access those properties and behaviors that you wish to use…

Here’s me demonstrate a simple scenario, how to override HTTPS Certificate Validation while using our Native HttpClientHandlers!

Full gist: https://gist.github.com/UdaraAlwis/0787f74796d22c294b91be81ff162347

Things Keep in mind!

So when you’re accessing the Native HttpClientHandlers in code there are some things you need to absolutely keep in your mind, to make sure the performance and security is not compromised.

– Custom bits, only Native level!

All the custom configuration that you need to do should be done in Native Xamarin level code, accordingly to native properties and behaviors.

– One time init() only!

You should instantiate your Native HttpClientHandler instances from Native level only once, and they shouldn’t be altered later for consistency during run time across your app.

– HttpMessageHandler, keep it as it is!

Keep the HttpMessageHandler instance that we up-cast from the Native HttpClientHandler instances as it is after instantiation, to make sure you’re not overriding any native properties and behaviors that we set up or inherited prior.

– Release Build, watch out!

When you’re using the Xamarin Platform specific Project Settings, make sure those settings are propagated to Release mode as well. In .csproj file has separate configurations for Debug and Release build configurations, so make sure keep an eye out for those configuration during Release builds as well.

Conclusion

Whenever you need to use the HttpClientHandler along side HttpClient, in your Xamarin.Forms or Native Xamarin Apps, its best to use the Native HttpClientHandler. This can be easily configured in each Native Project Settings or we can even instantiate them in code to be used across our Xamarin.Forms app environment as I’ve explained in this article.

I have shared the demo app code in my github as usual: github.com/XFNativeHttpClientHandler

Well that’s it! 😉

Share the love! Cheers!

Prepping your Xamarin.Forms App for Penetration Testing!

Let’s make sure your Xamarin.Forms App is ready for Penetration Testing, or widely known as PEN Testing! Focused on the Network Communication Layer, so that we can have a peace of mind for ourselves without being annoyed by our QA and Security Analysis team! 😉 lol

In any Mobile App Development project, we need to thoroughly test our Mobile Apps for vulnerabilities and security of user data. That is why these penetration testing processes are very important, we need to make sure that we deliver a mobile application as hardened and safe guarded as possible for our Users.

Now this post is not about securing or hardening the security of your mobile app, but rather how to prepare your Xamarin.Forms built app for QA and PEN Testing procedures.

But why, Xamarin.Forms?

Xamarin.Forms does an incredible job at producing a almost native-like level Mobile Application at the end of development. But given the unique nature of Xamarin.Forms, the .NET framework that we work with, sometimes developers take it for granted, giving all the responsibility to the framework, and we miss some bits that we need to pay attention to in oppose to native mobile development.

We need to make sure our App is compatible with the QA and PEN Testing procedures. Most of the QA and PEN testing revolves around the Native Mobile App environment. But sometimes those typical native mobile app testing processes aren’t compatible with what we work on out of the box of default .NET builds of Xamarin.Forms!

PEN Testing of a Mobile App…

Now there are many different kinds of QA procedures and PEN Test cases, such as local DB analysis, MiTM packet analysis, etc. In order to support those different PEN Test procedures, some times we need to provide separate builds with different configurations of your app to our PEN Test team. Such as disabling SSL Pinning in the app so that they can execute MiTM packet analysis testing on our app, and there could be many different scenarios as such.

So I’m going to share with you some of the important key points that you need to make sure you have configured in your Xamarin.Forms project, specifically in your Network Communication Layer and for some of those custom builds that you might have to provide for the PEN Testing process.

HttpClient Handler setup..

While Xamarin does provide a full fledged Managed HttpClient and Handler, it is best to set up the HattpClient’s handlers to the device native handlers. This will make sure better performance and better native system level security for your app.

On your Xamarin.Forms project solution, go to the Android project node -> Properties -> Android Options -> Click “Advanced” button and take a look at HttpClient implementation and SSL/TLS implementation.

Make sure to set them up as above using the native Android handler, and Default (Native TLS 1.2+) Transport Layer Security for all the web calls. This will make sure all our web endpoint calls will be handled by those configurations which are best suited for performance and security of the native android system.

Then for the iOS, On your Xamarin.Forms project solution, go to the iOS project node -> Properties -> iOS Build and take a look at HttpClient implementation.

Make sure its set to NSUrlSession handler, which will provide your iOS app with native iOS level security and better performance for web endpoint calls. Also this means your app won’t support devices before iOS version 7, so better check your app requirements as well.

HttpClient setup in Xamarin.Forms!

It is very crucial that you imperilment the use of HttpClient in your Xamarin.Forms app properly with performance and security in mind. It would be best to register the instance of HttpClient as a Singleton, and refer to that singular instance for all your web endpoint calls. This will not only make it easy for debugging, also easy for configuring your API/Web endpoint execution layer’s implementation.

And set up a HttpClientHandler to be passed into your HttpClient instance during the instantiation, so that we can include all the custom configuration easily.

Unless its a must, make sure to use the Native HttpClientHandlers for your HttpClient, which will increase the performance and native security features for your app.

  • Android: AndroidClientHandler
  • iOS: NSUrlSessionHandler
  • UWP: WinHttpHandler

Instead using the .NET Managed HttpClientHandler, use the above instances mapped up to your Xamarin.Forms shared environment. Here’s something that might be useful: Xamarin and the HttpClient For iOS, Android and Windows

Do not re-instantiate the same HttpClientHandler nor HttpClient instance during run time and keep those different configuration separately for each HttpClient by registering multiple types with a pre-defined use case. Such as AuthClient for handling authentication and ApiClient for normal endpoint calls.

Although there are third party HttpClient libraries such as ModernHttpClient, that provide better features for these specific scenarios, so you could even try one of them! 😉

Disable SSL Certificate Validation..

In case if you needed to disable HTTPS / SSL Certificate validation for your PEN Test procedures such as Man-in-The-Middle packet trace analysis, then we can easily disable this by overriding the Certificate validation execution in the HttpClientHandler and assigning that to HttpClient.

var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
	(message, certificate, chain, sslPolicyErrors) => true;

HttpClient = new HttpClient(handler);

 

The above applies of course if you have set up Managed HttpClientHandler in your Xamarin.Android and Xamarin.iOS settings instead of using the native handlers.

If you have set up your projects with Native HttpClientHandler then you can easily disable HTTPS Certificate validation by following ways.

For Android, create a Custom derived implementation of AndroidClientHandler as follows,

public class CustomAndroidClientHandler : AndroidClientHandler
{
	protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
	{
		request.Version = new System.Version(2, 0);
		return await base.SendAsync(request, cancellationToken);
	}

	protected override SSLSocketFactory ConfigureCustomSSLSocketFactory(HttpsURLConnection connection)
	{
		return SSLCertificateSocketFactory.GetInsecure(0, null);
	}

	protected override IHostnameVerifier GetSSLHostnameVerifier(HttpsURLConnection connection)
	{
		return new BypassHostnameVerifier();
	}
}

internal class BypassHostnameVerifier : Java.Lang.Object, IHostnameVerifier
{
	public bool Verify(string hostname, ISSLSession session)
	{
		return true;
	}
}

Based on: https://nicksnettravels.builttoroam.com/android-certificates/

for iOS, subscribe to TrustOverride and return true to override certificate validation.

var iosClientHandler = new NSUrlSessionHandler();
iosClientHandler.TrustOverride += (sender, trust) =>
{
	return true;
};

 

For UWP: subscribe to ServerCertificateValidationCallback and return true to override certificate validation.

var uwpClientHandler = new WinHttpHandler() 
{ 
	ServerCertificateValidationCallback = 
		(message, certificate2, arg3, arg4) =>
		{
			return true;
		}
};

 

As you can see in all the snippets above we’re overriding HTTPS Certificate Validation process manually. Now this is not a build to be pushed for Production, make sure to produce this build as a Test only build for PEN testing. So I would suggest keep this configuration in a separate branch build and opt back to the main branch for production release.

Enable Self-Signed SSL Certificates..

Instead of disabling entire SSL Certificate validation process, we could narrow down the override to a certain SSL Certificates, such as a Self-Signed Certificate endpoints that our PEN Testers might be using.

Although there are many ways to do this, basically we include the given self-signed certificate data in the app’s configuration, or override the validation with it’s key. I would recommend going into the following tutorials for it hence it covers a wide aspect of it for both iOS and Android.

Self Signed iOS Certifcates and Certificate Pinning in a Xamarin.Forms application

Self Signed Android Certificates and Certificate Pinning in Xamarin.Forms

So kudos to nicksnettravels blog! 😉 They’ve got great stuff in there!

Enable non-HTTPS!

As you know by default Android (since Android P) and iOS platforms doesn’t allow insecure non-HTTPS calls to be made from our apps,

Now we might have to disable this during development until the back end server is TSL enabled or even for a PEN test case with a custom build.

Let’s disable this on Android by using android:networkSecurityConfig in your AndroidManifest.xml with a reference to the @xml/network_security_config which we’ll create next.

<manifest ... >
    <application
        android:networkSecurityConfig="@xml/network_security_config"
        ... >
        <!-- Place child elements of <application> element here. -->
    </application>
</manifest>

 

Add a new folder called “xml” in your Resources folder and add a new xml file with the name network_security_config.xml this will hold the key to disable or enable HTTPS connections restriction as you wish.

<?xml version="1.0" encoding="utf-8" ?>
<network-security-config>
  <domain-config cleartextTrafficPermitted="true" />
</network-security-config>

 

You can set cleartextTrafficPermitted to false later during production build.

And on iOS add the following configuration in the info.plist file.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

 

Oh once again, make sure to disable this during PROD builds!

System Proxy Settings support!

Something to keep in mind is that you don’t need to worry about System Proxy settings as long as you’re using the Native HttpClientHandlers as they would by default use the system preferences under the hood, but if you’re using Managed .NET HttpClientHandlers then you need to handle the System native Proxy Settings.

You can do this by creating a Platform specific Service that will extract the System Proxy Settings, and you can use that when you’re instantiating HttpClientHanlder. This article provides a great example for it: HttpClient and Proxy

Is all good? 😉

Now before you ship out your build for the PEN test you can make sure everything is in place according to your specific requirements.

BadSSL (https://badssl.com/) is a great web tool to check whether your app is able to access non-https endpoints or self-signed certificate endpoints and so on based on your PEN Test requirement. You can call upon those test endpoints directly from your app to make sure they’re accessible or not.

Network monitoring tools like Fiddler and Charles Proxy, allows you to set up dummy local proxy servers that you can test with in order to make sure your app supports proxy communication or in that case App’s compatibility with using System proxy settings. You could even monitor the data streams going in and out of the app, and see if they’re properly secured with encryption.

So for this demo I prepared a little sample app which showcases the use of non-HTTPS, Self-Signed endpoints access, and Proxy settings reading capabilities. Check out below Android, iOS and UWP run times…

As you can see it’s able to go through all the defined scenarios I mentioned before. For this demo app I’m using all Native HttpClientHandlers, so I’m using the exact code snippets I’ve shared in this blog post. Now let me try to emulate some failure scenarios where its missing some configuration I shared in this post.

Full demo code: github.com/UdaraAlwis/XFPenTestPrepDemo

   

1st I’m emulating the instance where Self-Signed HTTPS endpoints unauthorized to execute as well as Non-HTTPS endpoints blocked by default System Security layer. 2nd one shows where the Self-Signed HTTPS is diabled but non-HTTPS endpoints allowed and so on to the 3rd scenario.

Well that’s it. Hope this helps you to configure your app properly with security in mind and provide builds for the PEN Test processes according to the requirements. 🙂

Share the love! Cheers! 😀

Stunning app Themes in Xamarin.Forms Shell projects!

Wanna build some awesome themes into your Xamarin.Forms Shell project? Change the App themes during the run time dynamically? Save the theme properties in User Settings? Then you’re at the right place! 😉

Themes in Xamarin.Forms Apps…

Given Xamarin.Forms is such an incredible cross platform mobile framework, it provides a lot of awesome features out of the box, but unfortunately it doesn’t straight away provide App Theme feature in your face. 😛  but…

It’s got all the bells and whistles you need to implement an awesome App Theme set up with ease, in combination of awesome Dynamic Binding, Static Binding and Style Properties giving you full control of how to handle implementing Themed Styles into your app. You just gotta put together all those bits and you can easily build App Themes functionality into the app.

This is actually quite powerful given the cross platform nature of Xamarin.Forms! Now there are plenty of documentation, articles and sample demos regarding this, so I’m not going to be repeating on that topic, but if you’re interested try out this office doc article from Microsoft: Theming a Xamarin.Forms Application Now that gives a very good step by step explanation on the topic for anyone to easily get started, but anyhow focusing back on this article…

Enters, Xamarin.Forms Shell Apps…

Then enters the recently introduced Xamarin.Forms Shell, a new paradigm of Xamarin.Forms App development. Now when I got started with this new awesomeness, I couldn’t find any direct articles or samples on how to implement App Themes in a Xamarin.Forms Shell projects.

So I had to figure it out myself, and that’s why I thought of sharing my experience with you guys. Now now, don’t get me wrong, since we’re still in the same context of Xamarin.Forms, the App Theming strategy is still the same as the official doc I shared about, but I may have found a better way and a bit of improvements on top of that. 😉

So let’s get started… Stunning app Themes in Xamarin.Forms Shell projects!

How to? in a nutshell!

Basically in a nutshell we’re going to define a set of Themes with Color Properties inside them that holds Color values unique to each Theme. Then we will build all a complete collection of Styles targeting all the components in our app such as Button, Labels and so on. Now in this case we need to stick to Dynamic Binding since we’re going to be switching between Themes during run time, so use of Xamarin.Forms DynamicResource binding all the way ah! 😉

Next we make sure all our UI elements are bounded to those Styles that we created before and still making sure to stick to Dynamic Binding. Now that we have established the binding chain from Theme Properties to Styles to UI Elements, we need to set up the default Theme to load in the ApplicationResources XAML node.

Once all that’s set up we shall be implementing a simple mechanism  to save the User’s App Theme preferences, with features such as Saving and Reloading those preferences on demand.

And that’s it! 😀

Sneak Peak!

Here’s a little sneaky peaky demo magic on Android and iOS.. 😉

If you’d like a sneak peak into the code before I get into the code details, you can find the whole demo project here in my github repo: https://github.com/UdaraAlwis/XFShellAdvThemeing

So in my demo code, I have used the default out of the box Xamarin.Forms Shell project template you get in Visual Studio 2019 latest update, so that you can easily familiarize yourself with the code and adopt the same implementation in your own code.

Set up of the project!

Let’s get started with the set up of the Project, but first should take a look into the structure we’re going to be implementing, where we need to first focus on the following aspects.

  • List of Themes for the App
  • List of properties in a given Theme
  • Styles built using the properties of Themes
  • Helper extension to change App Theme
  • Saving the User’s App Theme preferences

Now keeping those main aspects in mine, I’m going to assume that you have already set up your basic Xamarin.Forms Shell app project. I’m going to name my little demo as XFShellAdvThemeing, denoting Xamarin.Forms Shell Advanced Theme-ing! 😉

Alright there goes our Xamarin.Forms Shell App project, with strong base of MVVM baked in! You may have noticed I have added “Themes” folder, which will hold the App Themes that we’re going to create. And then a “Helpers” which will hold a simple extension method that we’re going to built for switching the App Theme selection by the user during run time.

Building the App Themes…

Time to define the App Themes, so first of all we need to be specific about what properties we are going to be using to each Theme, be it colors, fonts, images and so on, you need to be specific, and make sure all the Theme definitions follow the exact same format.

on github: /XFShellAdvThemeing/Models/Theme.cs

Here I have defined the list of Themes that I’m going to include in my App, and as for having the type of Enum, is for to be used later in the code to populate the data to the User. So make sure to add a record here every time you add a new Theme to your app.

This step is very crucial because you shouldn’t neglect this and try to change the app theme properties half way into the app development. If you’re working with a team,

…you need to define with the team designers together how the Themes of the app should behave, and what elements should be controlled over them.

For this demo I’m going to define the following list of properties inside each Theme.

  • Main Colors:
    • Primary Color
    • Accent Color
    • Secondary Color
  • Page Colors:
    • Page Background Color
    • Navigation Bar Color
  • Text Colors
    • Primary Text Color
    • Secondary Text Color
    • Tertiary Text Color

As you can see I have taken into consideration of having 3 set of main Colors, and as a back up since I’m going to be using native Navigation bar, a property to control its colors and the Page background as they render next to each other. Then finally the Colors for the Text inside the app.

Its very crucial you develop this kind of design centric thinking when you’re developing any mobile app…

So let’s create our beautiful little XAML snippets inside the Themes folder that are going to hold all the properties of each App Theme.

Just simply add a XAML page into the Themes folder and rename the parent node to ResourceDictionary of type and update the same in the code behind as well.

on github: /XFShellAdvThemeing/Themes/DarkTheme.xaml

There my first theme, LightTheme which holds the color values I need to customize in my app for Theme-ing! 😉 Feel free to add as many themes as you like following the same structure.

Defining the Styles…

Now these bits are the middle man between your UI elements and the Theme definitions. As I explained before we are going to create Styles targeting all the types of UI Elements that we’re using in the app, so that we can “Style” them with those! 😉 get it!? lol

on github: /XFShellAdvThemeing/App.xaml

You can define these Styles as a Global App resources or in Page levels as you wish, but I have added them into my App.xaml for this demo, such as Styles targeting Buttons, Labels, etc.

As you can see we are using DynamicResource binding to hold on to the Theme property values, so that we can update our Style property values dynamically in run time.

Now you might wonder why I have referenced Themes/LightTheme.xaml in the  global Resource Dictionary, well… that is to set the default theme as the Light App Theme that I just defined above. You can keep it as it is or watch me switch the App Theme dynamically during run time below… 😉

You also need to directly reference your Shell bound UI Elements using the Theme properties we defined earlier. Here I have added to to the same App.xaml global scope instead of keeping it in the AppShell.xaml scope, just for organizing the styles in one place.

Switching App Theme Dynamically…

Now of course we need to allow our App to be able to switch the Theme dynamically during run time according to User’s choice or some configuration built in. We can easily do this in Xamarin.Forms, using MergedDictionaries property by removing the existing Theme in memory Resources and switching to our choice of Theme Resources.

I have created a simple Helper extension, with the method SetAppTheme() which accepts the type of Them Enum value you need to use and returns the boolean result.

on github: /XFShellAdvThemeing/Helpers/ThemeHelper.cs

Like I said before this is where out little Helper extension comes into play, so just add this little snippet into your Helpers folder.

Based on the Theme Enum identifier value, we will be instantiating the Theme object, assigning it to the Resources in memory as you see above.

Now that’s all cool and stuff, but how about persisting this preferred theme selection?

Saving to User Preferences!

This can easily be done with the help of Xamarin.Essentials, which allows us to save Application context key values pairs using the Preferences API. Now I believe in Visual Studio when you create a new Xamarin.Forms Shell project by default it comes pre-installed with Xamarin.Essentials, otherwise make sure to add it to your project from nuget.

We are going to save the Selected App Theme settings with the key name “CurrentAppTheme” as below.

on github: /XFShellAdvThemeing/Views/ThemeSelectionPage.xaml.cs

And make sure to load it back to the app during the App’s launch event and call up on our little magic extension ThemeHelper.SetAppTheme() as shown here..

on github: /XFShellAdvThemeing/App.xaml.cs

You need to call that in the App() constructor invoke, so that we can load the saved App Theme settings instead of loading the default one that we set up in App.xaml resources.

 

Bingo! nice little App Theme Selection Page to our Xamarin.Forms Shell App! 🙂

Time for some action!

Here it is side by side iOS and Android,

 

Themes with more than Colors?

Now our App Themes aren’t always going to be as simple as a bunch of Color properties right?! It could even contain Fonts, Text Sizes, Images, Icons and so on. But if you’re wondering if that’s even possible in Xamarin.Forms, yes absolutely you can!

It’s basically no different than defining a Color property in your Theme.xaml file, just add the XAML node to the file and you’re good to go!

Make sure to give it a Key name value though, and reference it in your Styles as usual where applicable.

You can follow the same pattern for any kind of Theme property you want to add and basically you’re good to go! 😉

Github Repo: github.com/UdaraAlwis/XFShellAdvThemeing

Any property that you can reference usually from your XAML, you can easily include them in your App Theme and link the binding through Styles to your UI elements straight away.

Some Tips!

Here are some tips and tricks that might come in handy for you, during the whole shabang of “Theme-ing” your Xamarin.Forms Shell app projects.

More Unification! Less Repetition!

Make sure to avoid adding repetitive theme properties into the Theme XAML definitions, by unifying the Colors, Fonts, Icons you use in your app. As an example if you define a Text Color property in your Theme, make sure to use that only for Text Coloring Elements and Styles, try not to use them for other aspects.

So you can easily manage those properties in future and they’d be easy to understand for anyone to extend the properties. This is quite crucial when you maintain massive App Projects, and it wouldn’t affect the capability to grow the App code altogether.

Stubborn Native Elements?! Yikes!

Now as you probably know or don’t Xamarin.Forms doesn’t let you change the color values of your App’s few very native elements during run time. Such as,

– iOS/Android System Status Bar Colors

– Android UI Elements that contains horizontal bar such as Entry, Picker, etc. (Unless you’re using Xamarin.Forms Material Visual)

They require native Android/iOS level access to change during run time. So you need to have Custom Renderers or Native Bound Services that can be communicated through Xamarin.Forms layer during run time. Well that’s a blog post for another time! 😉

So here’s how it could be easily solved as you can see below,

My suggestion would be to maintain values of those UI elements as compatible as possible that could be matched with the Theme Colors you currently use. Such as light Gray, White or Black mostly.

You can easily set them up from Resources/values/styles.xml in your Android project.

And on iOS project’s Info.plist configuration.

And that’s pretty much it!

Share the love! 😀 Cheers!

Using SMS Retriever API in Xamarin Android!

Let’s use the SMS Retriever API in Xamarin Android, and possibly avoid the troubles of new Google Play Store SMS/Call Log access restrictions! 😉 Is your Android App ready for the new Google Play Store permission policy?

SMS Retriever API, in a nutshell…

Android SMS Retriever API allows you to access the SMS Messages in the phone without having to request SMS read access permission, thus giving a complete peace of mind for the user. 🙂 Allowing specific SMS messages to be read from the Inbox, which are specifically targeted to be delivered for the  app we’re requesting from. This is the perfect solution for One Time Password (OTP) mobile number verification implementation in our Android apps.

Furthermore from Google Docs: https://developers.google.com/identity/sms-retriever/

Now that the introduction is out of the way… Let’s get started!

How it works, in short…

NO! I’m not gonna get into detailed explanation, but in simplest terms we are going to have an object called SmsRetrieverClient that’s going to wait for an incoming SMS message with the matching hash key to the app we are using. This active waiting is going to execute for 5 minutes and automatically dispose itself.

When the certain SMS arrived at the inbox during the 5 minute waiting , the SmsRetrieverClient then sends a broadcast to the app with the captured message content, for any listening broadcast receivers registered in the app.  From there we pick up the message inside our broadcast receiver and we process it or do whatever the heck we want with it. 😛

But in case if the SMS wasn’t received by the phone it would still execute the broadcast but with a time out failure code, so that we know the 5 minutes waiting exceeded and the SMS wasn’t received or read.

So there’s mainly 2 components to it, SmsRetrieverClient object, and the Broadcast Receiver object. Not to mention the App Hash key, which is also very crucial element here, you need to make sure the SMS that’s sent to the device has the App hash key that’s derived from the signing keystore of the app’s running instance.

In Xamarin…

Yes this is completely available in Xamarin Android as well, right out of the box! Just a matter of figuring out the right namespaces and method calls comparing to the official Google Android Docs! 🙂

Although I’m quite surprised I could not find any official Documentation from Xamarin regarding this important API. Thus here I am filling that void! 😀

Let’s get started!

Add em Nuget!

To use SMS Retriever API in Xamarin we need to install Xamarin.GooglePlayServices.Auth nuget package to our Android project.

Just pick the latest version as you prefer and hit install.

Activate the SMSRetrieverClient…

Then we need to implement the executing of the activation of SMSRetrieverClient that is the client object that’s going to actively watch out for any incoming SMS messages with the hash key that is similar to the app we are requesting it from.

You could initiate the SMSRetrieverClient inside a button click event or invoke it from a Service instance method, choice is up to you. 🙂

private void btnStartSMSRetreiver_OnClick(object sender, EventArgs eventArgs)
{
	// Get an instance of SmsRetrieverClient, used to start listening for a matching SMS message.
	SmsRetrieverClient _client = SmsRetriever.GetClient(this.ApplicationContext);
	// Starts SmsRetriever, which waits for ONE matching SMS message until timeout
	// (5 minutes). The matching SMS message will be sent via a Broadcast Intent with
	// action SmsRetriever#SMS_RETRIEVED_ACTION.
	_client.StartSmsRetriever();
}

As you can see we’re instantiating the SmsRetrieverClient using the Application Context, and calling the StartSmsRetriever() method to activate listening to the incoming SMS messages with matching app hash key included.

A little cherry on top…

Here are some extra bits you could adopt if needed regarding the SmsRetrieverClient. You could get the return result of the SmsRetrieverClient initiation as follows…

...

	var task = _client.StartSmsRetriever();

	// You could also Listen for success/failure of StartSmsRetriever initiation
	task.AddOnSuccessListener(new SuccessListener());
	task.AddOnFailureListener(new FailureListener());
}

...

internal class SuccessListener : Java.Lang.Object, IOnSuccessListener
{
	public void OnSuccess(Object result)
	{
		// do as you wish on Success init
	}
}

internal class FailureListener : Java.Lang.Throwable, IOnFailureListener
{
	public void OnFailure(Exception e)
	{
		// do as you wish on Failure init
	}
}

And even await for the init result asynchronously as follows…

var task = await _client.StartSmsRetriever();

But don’t forget to switch the caller method to an async method! 😉

Well that’s just some cherry on top features if you ever wanted to try!

Next the BroadcastReceiver…

So here’s the other piece of the puzzle, the BroadcastReceiver that will be listening to the broadcasts of the above SmsRetreieverClient.

SMS Retriever API has provided us with an intent filter SmsRetriever.SmsRetrievedAction which we will use to register our BroadcastReceiver, which we’re going name as SMSBroadcastReceiver, and implement as following…

[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { SmsRetriever.SmsRetrievedAction })]
public class SMSBroadcastReceiver : BroadcastReceiver
{
	public override void OnReceive(Context context, Intent intent)
	{
		if (intent.Action != SmsRetriever.SmsRetrievedAction)
			return;

		var extrasBundleundle = intent.Extras;
		if (extrasBundleundle == null) return;
		var status = (Statuses)extrasBundleundle.Get(SmsRetriever.ExtraStatus);
		switch (status.StatusCode)
		{
			case CommonStatusCodes.Success:
				// Get SMS message contents
				var messageContent = (string)extrasBundleundle.Get(SmsRetriever.ExtraSmsMessage);
				// Extract one-time code from the message and complete verification
				// by sending the code back to your server.
				ShowResultOnUI("SMS retrieved: " + messageContent);
				break;

			case CommonStatusCodes.Timeout:
				// Waiting for SMS timed out (5 minutes)
				// Handle the error ...
				ShowResultOnUI("Timed Out Error! SMS retrieval failed!");
				break;
		}
	}
}

So once the SmsRetrieverClient does its job, either success or failure it will hit our Broadcast Receiver above and pass in the results, with Status code and Content of the Message if success, which will be included in the Extra Bundle as you can see above.

Once we receive the results, its up to you to do whatever you want with it, as you can see in the code itself! 😉

That’s pretty much it! simple and straightforward eh! 😀 But I wouldn’t end there without mentioning some important other bits that you need to make sure to get it right!

Other important bits…

Here are some helpful tips for you to troubleshoot any issues you’re having with getting the SMS Retriever API to function as it should.

SMS format..

You need to make sure you’re sending the correct SMS format as mentioned in the Google Android Documentation.

<#> Your ExampleApp code is: 123ABC78
FA+9qCX9VSu

It should be same format as above, although you could make some alterations to the message content, but the structure should be same. Start with “<#>” followed by the content of the SMS and ending with the App Hash key. You can learn more about it from their documentation: SMS Retriever API: Construct a verification message

Please, get your App Hash Key right!

I’ve seen people get this wrong all the time. It is such an easy simple process but a delicate one. So if you can’t get your implementation of SMS Retriever API to function properly, you should definitely take a look at your app hash key, whether you’ve generated the correct key and using the properly in the SMS content.

Given Xamarin Android development, there’s no official documentation provided by Xamarin yet, that’s why I have written a step by step blog article to how to easily generate the accurate App hash key, give it a try if it could be of any help…

You can check it out here: App Hash Key Helper extension for Xamarin Android apps!

Let’s see it in action! 😀

Let’s fire it up and see the beauty of Android SMS Retriever API in Xamarin!

Look at the beauty eh! 😀 No SMS Read permission required 😉 way to give some peace of mind for your users for a simple functionalities such as OTP or Phone number verification!

You can try out my full blown demo in my github repo:

https://github.com/UdaraAlwis/XAndroidSMSRetrieverAPIDemo

It’s got all the bits I talked about above fully functional 🙂

in Xamarin.Forms Android?

Even if you’re using Xamarin.Forms the same implementation above can be applied easily. Just simply create a platform specific service to invoke the SMSRetrieverAPIClient on Android and call it from Xamarin.Forms at run time, then from the BroadcastReceiver just return back the results by using Xamarin.Forms MessagingCenter… 😉

Simple eh! 😀

There you have it fellas!

Cheers! Share the love! 😀 ❤

App Hash Key Helper extension for Xamarin Android apps!

Remember my last post “Generating App Hash key for SMS Retriever API for (Xamarin incl.)…” where I shared with you guys how to successfully  generating the App hash key in both MacOs and Windows environments without any hassle?

Now this is the improved alternative of it! making the whole process much easier specially for Xamarin Android development!

Previously…

So earlier we looked at how we could generate the App Hash key straight away from MacOS Terminal or on Windows with the keystore hex generation followed by the Xamarin Android helper method execution to retrieve the app hash key!

That specific helper method I had extracted partially from the Google’s official documentation sample regarding the SMS Retriever API, which I couldn’t completely port to Xamarin Android at that time while I was working on my private project.

But later I took a proper look at it and figured out how to completely port it to Xamarin Android, with a few minutes of back and forth between the Java code and C# Xamarin namespaces! 😀

Easier and Faster method!

Now with the fully ported code, as an extension helper class, we could easily generate the Hash key for our Xamarin Android app either on Windows or Mac using Visual Studio, without having to use any external Terminal or Command prompt.

but you need to follow some pre-requisites to get it to properly work..

Let’s get started!

Get your pre-requisites right!

You need to make sure you’re using the correct Keystore file to sign your APK during build, therefore navigate to your Xamarin Android project properties and set the correct Keystore file path and configuration.

In Visual Studio on Windows:

In Visual Studio on Mac:

That’s done!

Finally make sure you have given the proper app package name or app id to your app in the same project properties. ex: com.testapp.xyz

Why you ask? Since we’re directly generating the app hash code from the project itself, we need to make sure during the compilation the app, the final APK is signed using the keystore we are hoping to use in production. So we can retrieved the signed hash hex from the app Context at run time and the app id to generate the app hash code. 🙂

Then let’s begin the AppHashKeyHelper implementation… 😉

Let the implementation begin…

Let the implementation begin! lol 😀 So here is the complete ported helper class for generating the app hash key for your Xamarin Android app!

Simply copy the whole code to anywhere in your Xamarin Android project, and you could straight away call it from anywhere in the app to generate the app hash key!

We’re simply passing in the Android App Context, which will then first retrieve the signed kestore hash string from the Package Manager.

Then we retrieve the app package name from the Context itself, and move ahead with the usual encrypted key generation.

I would recommend calling this from your MainActivity itself, since this is just a one time execution in your local debug environment.

There you go! Simple as that! 😀

Now once again, keeping in mind to make sure to remove the above helper class call from your project code, before you submit your final APK to the Play Store, since google does not recommend generating the App’s hash key during user run time. Just simply retrive your hash key and remove the code, and then set it up in your SMS API gateway execution.

Thats it! 😀

Cheers!

Share the love! 😀 ❤

Generating App Hash key for SMS Retriever API for (Xamarin incl.)…

Trying to generate your app’s Hash Key for the implementation of new Android SMS Retriever API? Still couldn’t get it to work? Well the problem could be in the actual generation process of the has string!

And here are some ways you could actually make sure to generate the valid hash string to get the functionality working.

Specially if you’re developing on Windows, or better working on a Xamarin Android app? I’ve got some goodies to make it work as well! 😉

App Hash string for SMS Retriever API

Anyhow, to use the SMS Retriever API we need generate our App’s unique Hash string which is a combination of app’s package name and your app’s public key certificate. Once the SMS is received into the Inbox the SMS Retriever API looks for any matching hash key in the message corresponding to the app that requested to read the SMS, if it finds a perfect match it will kick in the execution of retrieving the SMS string, otherwise it will time out. So without the accurate app hash key the SMS Retriever API will not kick in at all. That is why it is very crucial we generate the correct app hash key for our app using the App package name and keystore hash.

Troublesome!

Although according to the official Google Documentation, it should be easy and straight forward, but it is not, specially if you’re using a Windows Dev Environment, which could be troublesome at times. To add some topping on to that, if you’re working on a Xamarin Android project in Windows, you’re in deep troublesome waters, since even Google Docs only provides samples for the Android Java implementation.

Then the sample command that Google Docs provide doesn’t really throw any error if anything goes wrong during, wrong parameter, or a wrong keyword, during hash string generation, it simply returns a false hash string, which makes things worse!

This is actually something I experienced while I was developing one of our Xamarin Android applications. Oh yes! that’s even more annoying since there’s no official documentation or Xamarin sample of the implementation code regarding that API. 😦

Hence Google’s doc command failed me I had to play around with the parameters we’re passing in to the command, re-arrange and modify to get it to work. But anyhow with a walk in the midst of the dark forest of troubleshooting, I figured out how to properly generate the App Hash key!

Get your pre-requisites right!

First of all prepare your keystore file path, keystore alias name and keystore password, and double check those values are being properly set. This is where most of them goes wrong. Then the obvious requirement, make sure you have Androd

Method 1: On MacOS Terminal

So this is the easiest and most straight forward way to generate the hash string, by simply executing the below command on a MacOS Terminal.

keytool -exportcert -alias <keystore alias name> -keystore <keystore file with extension> | xxd -p | tr -d "[:space:]" | echo -n <your app id> `cat` | sha256sum | tr -d "[:space:]-" | xxd -r -p | base64 | cut -c1-11
  • Replace the <keystore alias name> with your keystore alias name, ex: mykeystorename
  • Replace the <keystore file with extension> with the full path to your keystore file, ex: /Users/username/Desktop/mykeystorefile.keystore
  • Replace the <your app id> with your app id: com.mytest.app

If everything went well, next line Terminal will immediately prompt you to enter the keystore password, which will generate the accurate app hash key!

Yep simple as that! 😀

Now you might wonder how I shared the above screenshot so bravely without worrying about the security, oh well its just using the default Xamarin Android keystore generated by VS for Mac with its default settings and a fake app id! 😛

Troublesome? Get Utils installed!

Unless you got some missing utils in your mac developer machine, such as the following error: sha256sum: command not found, which indicates missing coreutils in your Mac. Therefore you need to fist install Homebrew if you don’t have already.

Install Homebrew: https://brew.sh/

Restart Terminal and run the below command!

brew install coreutils

Restart Terminal and re-run the has generation command! 🙂

Method 2: On Windows CMD Prompt

Now on Windows its going to be a little bit of more work specially most of the command parameters which are used in unix cannot be executed straight up in Windows Command Prompt.

So in hope of avoiding at least a little bit of pain I would recommend using the Visual Studio Command Prompt or the Android ADB Command Prompt in your Windows PC. Specially since the java keytool path should already be configured in the Path property there.

Step 1: Generate the hex string from keystore file

keytool -alias <keystore alias name> -exportcert -keystore "<keystore file with extension>" -storepass "<keystore password>" | xxd -p

Now the parameters that you need to replace are the same as we did on MacOS command, but as you can see keystore file path and password are provided within brackets or quotations. So make sure to add that detail.

If everything went well, it will return you the hex string from your keystore file!

Now that’s me trying out the default debug keystore file in Windows. If everything executes properly, it should return a super long hex string as shown above, actually even much longer than that lol, I just cropped it out 😛

Copy that hex string and keep it, we are gonna use it in the next step.

Step 2: Implement the Hash key generate code script

Next we’re going to port the Google Doc’s Android Java implementation of the Hash key generation execution to Xamarin Android C# code snippet, thanks to my few minutes of trail and error efforts 😛

Simply copy that snippet into a Xamarin Android project with the specific imports mentioned at the top of the snippet. You could use this as a little helper extension method to generate the app hash key by passing in the app package name and keystore hash value that we generated in the step 1, as mentioned in the parameters.

That should work like a charm! 😀

Although keep in mind once you generate the app hash string, you should remove the keystore hex and package name hex from the code before you submit it to the app store. Google does not recommend those sensitive information inside the code as magic strings due to obvious security reasons.

Now the above code snippet can be used in either Visual Studio on Windows or Mac as long as you got the keystore hex string. 😉

TADAAA! 😀 That’s it!

You’re welcome!

Share the love! 😉 ❤

Is your Android App ready for the new Google Play Store permission policy?

Not so long ago in October, 2018 Google has announced a new policy regarding the use of SMS and Call Log access permissions in your Android apps.

“Providing a safe and secure experience for our users. – Android Developers Blog, Google”

“Google is restricting which apps can request Call Log and SMS permissions – XDA Developers”

Which created quite a buzz amongst the Android Developer community, by short it means Google is restricting the access to the user’s SMS and Call logs from our Android apps, which is actually a step forward to protect the user’s privacy and security.

Root cause…

Since the beginning on Android you could gain access directly to read the user’s SMS and Call logs on android upon permission request, and your app didn’t have to be registered as a Phone or SMS handler app to perform this action. Any app could easily ask for permission from user and gain access to SMS functionality and Call logs seamlessly.

After a while,

some apps had actually started to misuse this open access, and violate user’s private data continuously…

As a fellow developer, speaking of this matter it was just a matter of getting the user to permit the one time permission and setting up the broadcast receiver to reading the messages forever even in background, which was a very easy and open access which could have easily misused for any illegal activity.  And frankly since this was just a one time permission access thing, the user wouldn’t really be aware of what’s going on in the background. :O

And frankly even for a small feature such as OTP we had to gain access to reading the whole list of SMS data in the phone, which was kind of way too much access in my opinion for such a simple task.

Restricting it up!

So Google has started to crack down on this issue as such..

“Some Android apps ask for permission to access a user’s phone (including call logs) and SMS data. Going forward, Google Play will limit which apps are allowed to ask for these permissions. Only an app that has been selected as a user’s default app for making calls or text messages will be able to access call logs and SMS, respectively.”

– Google

Well done Google! now that’s how it’s done. 😀

So frankly what Google is saying as the new policy is that your app will not be given SMS and Call log access permission unless user has selected your app as the default system SMS or Call provider app.

Unless your app’s “core functionality” is related to SMS or Call logs, such as a SMS Sender/Reader or a Call log recording app or something similar of sorts, your app will not be granted access. Otherwise you’re going to have to revert to other API’s Google has provided to access SMS and Call logs for minor functionalities such as OTP verification and so on. 🙂

Now that was back in October, 2018!

Don’t comply? App will be blocked!

Yep they first gave a grace period of 90 days and now they are bringing the rain down upon the apps…

“Reminder SMS/Call Log Policy Changes – Android Developers Blog, Google”

“Google will remove unapproved apps that use call log/SMS permissions in the next few weeks – XDA Developers”

So they have begun cracking down on the apps that are already in the Play Store which does not comply with the new policy of accessing the SMS/Call logs information.

It’s now being striclty mentioned in the Play Store Developer Policy Center: https://play.google.com/about/privacy-security-deception/permissions/

But this doesn’t mean they wouldn’t give any exceptions, in cases like if it is heavily required for the app’s core functionality, as if it’s a sub-functionality that could break the core flow of the app. In which case you will be able to submit a special review for an exception.

So what solution?

This is where you need to take a hard look at your app’s functionality and decide what is core functionality and what’s a side feature.

They have defined this very well in their new updated help document:

“Use of SMS or Call Log permission groups – Play Console Help, Google”

let me put it frankly.

Not Core Functionality but still needed!

This are the instances where it would really not break the core functionality of your app, but it is still required for some other sub-functionality in your app?

Such as for an example, let’s say SMS OTP verification? In that case you could use Google’s alternate API to access SMS OTP retriever API, which doesn’t require SMS access Permission from user. 😀

So they have also given a list of alternate possible APIs you could use to fulfil the requirement without having need the access to SMS/Call logs information.

https://support.google.com/googleplay/android-developer/answer/9047303

Once you have implemented the alternate API use, then you should submit a new version to Play Store without the mentioned permissions.

Core Functionality!

So this is where you need to define the use of your app, is your app an actual SMS Sender/Reader app such as Messenger? or a Call Log keeping app? which then can be defined as a the core functionality of your app. In that case you could continue using the access to the information as long as the user has set your app as the default phone SMS or Call service provider.

But if it is not a default Messenger or Caller app and still needed the access permissions for core functionality then…

“Submit a new version of your app that retains the permissions. Doing so will require you to complete a permissions declaration form inside the Play Console (coming soon) and will give you an extension until March 9th to remove the permissions or receive approval for your use case.”

– Android Developers Blog, Google

If accessing SMS/Call logs is required for a main functionality and you believe it does not violate the policies then you could submit a Declaration Form in Google Play Store, requesting for manual review to exclude your app from removal from Play Store.

They may provide a temporary exception to apps that aren’t Default SMS, Phone, or Assistant handlers when certain scenarios aren’t possible to achieve without such permission access, which is defined in the Exceptions section in “Use of SMS or Call Log permission groups – Play Console Help, Google”

In Conclusion…

Now this actually is going to break a lot of cool features of apps, which may or may not be violating user’s sensitive information. But still it’s a one big step forward for gaining the Android User’s trust and making them feel positive about using your app in long term. 🙂

Again that I’m saying this is going to prevent some really cool apps being pushed to public market via Play Store though. 😐 but a much needed restriction…

XAMVVM-01 A real walk-through of Xamarin.UITest with Xamarin.Forms!

Let’s take a chilled out walk through adding Xamarin.UITests to your Xamarin.Forms project! 😉

When I said chilled out, I meant literally a chill, no-fuss walk through adding UITests for your Xamarin.Forms project solution. There’s many articles and tutorials out there regarding this, but when I first started I couldn’t find a clear enough guide to begin with for myself, so I was stumbling around in confusion here and there until I self-learned a proper foundation. That’s why I thought of writing this post.

This is an attempt of sharing my experience and intuition of how to architect a better UITest structure for your Xamarin.Forms Solution helping you to get a clear and easy head start!

So I’m not gonna get into extreme baby steps, or details, but a clear fuss-free hands-on guide for starting off with your UITests, which I hope would give you a clear picture and understand of the whole shabang! After all I’m all about that solid project architecture!

Why UITests?

Hey, if you’re looking for a serious intro, please Google! I don’t like repetition of content lol.

Xamarin.UITests comes in handy when you want to have consistent assurance of the actual functionality of the app with the UI behaviour included. And between you and me, I actually love watching UITests being executed on Devices and Simulators, seeing you app actually being used like a human, giving you a whole feedback loop of the UI behaviour , is just an incredible experience! 😉

 

Let’s get started..

Just for the showcase of this awesomeness, I created a little App, which is called Textpad, where you simple take notes or texts of whatever you feel like. 😉 A very simple out of the box Xamarin.Forms app, and fully MVVM architectured code base with Prism. I named the solution as “XFWithUITest” just for this demo.

Whatever the default template of the Xamarin.UITest has provided, I have done several changes to it here and there for the clarity and of the code base as you will see in this article.

So I’m gonna walk you through a clean and well-structured manner of adding Xamarin.UITests to your project solution.

You can take a little sneak peak at it over here in my github repo:
XAMVVM-Playground/XFWithUITest

Structure is important!

There’s many ways to structure a UITest, but I like a clean separation of the elements in any solution architecture. Like here we’re going to separate our Tests from the actual Host projects.

So first, for the name of separation let’s add a Folder called “Tests” in your Xamarin.Forms solution. Yes, that’s the way to start!

Then let’s create our Xamarin.UITest project, right-click on the “Tests” folder in the VS Solution Explorer and go to Test tab and select Xamarin.UITest Cross-Platform Test Project!

Also pay extra attention to the Name and Location value for our UITest project. Append “.UITest” at the end of your project name. As of the location, make sure to add the path along with the “Tests” folder that we created above.

Next create a new Folder inside of that project called “Tests”, yes another one, which is where we’re actually placing our tests! Also create a new class called SetupHooks, which is where we’ll maintain all the hooks that are needed for our tests. (I’ll get into details for this in a later step)

Now it should look something like this!

Nothing more.

Delete anything else that’s unnecessary or not seen above! 😉

Off to next step!

Don’t forget the nugets!

Make sure all the necessary nuget packages are in place, which is just basically the following 3 nugets! yep that’s it!

Pay very careful attention here to the version of NUnit version 2.6.4, which is the minimum NUnit version supported by Xamarin.UITest as of today. (01/11/2018)

The deal with AppInitializer!

Now this right here is where your Tests will be firing up the app’s execution. There are many ways to structure this class and its functionality, but here’s my way…

This class comes pre-populated when you first create the UITest project, but I have made some changes of my own for the clarity of the code.

As you can see I’m passing in an extra boolean parameter “clearData”, which is to execute a clean instance of my App for testing.

I’m using the InstalledApp() call to load the Android and the iOS apps from the simulators, also I’m enabling the EnableLocalScreenshots() to get actual screenshots of my test instances as I wish. Yeah the fact that you can automatically capture screenshots during testing even when you run locally is really cool feature of Xamarin.UITests! 😉

Now instead of getting a hook on the InstalledApp(), you could use the path to the APK or IPA file using the ApkPath() or AppBundle() respective for Android and iOS, which is totally up to your choice.

Then I’m passing in the AppDataMode parameter according to my choosing of the “clearData” value.

SetupHooks holds the instances!

Remember earlier I created a class called SetupHooks? let’s set it up now!

public class SetupHooks
{
      public static IApp App { get; set; }

      public static Platform Platform { get; set; }
}

 

During UITests execution we’re holding a singular instance of the app in memory, which we’re calling through UITest’s functions to perform many operations, so to simplify that, here we’re holding a public static instance of the IApp and Platform object to be used in our Test cases.

Pretty neat eh! 😀

Let’s write the Tests!

Create a class called AppTests, which is where we’re going to place the Test fire up code and the rest of the tests for now!

namespace XFWithUITest.UITest.Tests
{
    [TestFixture(Platform.Android)]
    //[TestFixture(Platform.iOS)]
    public class AppTests
    { 
        public AppTests(Platform platform)
        {
            SetupHooks.Platform = platform;
        }

        [SetUp]
        public void BeforeEachTest()
        {
            SetupHooks.App =  
            AppInitializer.StartApp(SetupHooks.Platform, true);
        }

        [Test]
        ...
	// test cases begin here...
		
	}
}

 

There I have added the TestFixture attributes as required by NUnit to identify our tests, and notice how I have commented out the iOS platform, to show you that you could stick to one platform at a time for your ease of testing, instead of seeing failed tests in the Test Runner window! 😉

[SetUp] is where your Tests will initialize the actual App instance, thus retrieving a hook to the app’s instance for our Test cases to use.

You can see how I’m tying up the SetupHooks – Platform and App instances, through the initiation of the AppTests.

AppInitializer.StartApp(SetupHooks.Platform, true);

This gives a clean instance of the app for our tests cases to use, and up on your wish you could pass in “false” to the same method and get a data persisted instance of the app at anytime, anywhere in your tests! 😉

Now you’re all set to start writing your UITests, but before we begin I need you to check up on something else!

AutomationId for everything!

Whatever the UI element you need to get a hook on to or get a reference of, be it a Page, Button, Layout even a Label, you need to add a value to its AutomationId.

And make sure every AutomationId in a given Page context is unique for every element, otherwise the look up function will return all the elements that matches the given Id, which could lead to confusion in your tests 😉

IApp interface functions!

The Xamarin.UITest.IApp interface provides a whole bunch of functionalities for the app for us to play around with in order to execute our test scenarios.

Take a look here, Xamarin.UITest.IApp to see the list of powerful functions we can use. To name a few are Tap, Swipe, Scroll, WaitForElement and etc, to be performed on any given UI Element on the screen.

So now all you need to do is get a hook on any given element..

Getting a hook on an Element…

There’s several ways of doing this, most common is by the AutomationId of the Element

SetupHooks.App.Tap(c => c.Marked("Button1"))

Another is by the value of an Element’s property,

SetupHooks.App.Tap(c => c.Text("Click this Button!"))

Or you could do by even the Class name of the element. Choice is completely yours, pick the one best suited for your test case.

How to write a Test?

Now this is the coolest part, Xamarin.UITest allows us to get hooks on to UI Elements of the running App, then we perform actions on those elements and wait for the results and check if it resulted as expected through assertion using NUnit.

So its basically a little dance between Xamarin.UITest and NUnit Assertion! 😉

As a standard keep in mind to append “Test” at the end of each of your Test cases.

As you can see above I’m first waiting for the HomePage to appear, then I’m asserting it through NUnit. Then I look for the Label with “Hey there, Welcome!” text!

Action and Result, simple as that! 😀

Some advanced bits…

Here’s some advanced bits that could come in handy!

Getting the number of elements in a ListView
SetupHooks.App.Query(c => c.Marked("TextListView").Child()).Length
Getting an element in a ListView
Func<AppQuery, AppQuery> itemInListView = null;

if (SetupHooks.Platform == Platform.Android)
     itemInListView = 
     x => x.Class("ViewCellRenderer_ViewCellContainer").Index(0);
else if (SetupHooks.Platform == Platform.iOS)
     itemInListView = 
     x => x.Marked("<your listview automationId>").Index(0);

// change the index parameter to get the item you wish
Opening Context Menu in a ListView item
// pop up the Context menu in ListView item
if (SetupHooks.Platform == Platform.Android)
      SetupHooks.App.TouchAndHold(firstCellInListView);
else if (SetupHooks.Platform == Platform.iOS)
      SetupHooks.App.SwipeRightToLeft(firstCellInListView);
Enter Text into an Entry or Editor
SetupHooks.App.EnterText(
c => c.Marked("TextTitleEditor"), whateverYourText);
Wait for an element to disappear
SetupHooks.App.WaitForNoElement(c => c.Text("This label text"));

// either by Text or Marked as should work
Restarting the app anywhere…
// restarting app, persisting state

SetupHooks.App = AppInitializer.StartApp(SetupHooks.Platform, false);

Check out more here in this awesome git page: XamarinTestCloudReference

REPL is your tool!

Yes start using the REPL command line to see how your App’s UI is actually rendered by the native platform at any given execution time. Simply call this anywhere you wish in the UITests steps,

App.REPL();

And you’ll be presented with a CLI which will help you see the whole UI tree of the screen. Simply type “tree” in the CLI and you’re good!

Structuring the tests..

Now there’s many ways to structure all the test cases and scenarios, and there’s no strict standard way that should be followed, but whatever you’re comfortable or fits your project is totally fine and the choice is yours!

You could include all your Test cases in the AppTest class itself, or you can break them into separate classes regarding the Page, or the functionality type.

So for this demo I’m keeping all my UITest cases in the AppTest class itself.

Running the UITests locally!

Well now that we have structured the architecture, here’s the time for actual firing things up and you’ve got couple of things to remember!

You can run your Android Tests on Simulator and Device directly without any modification as long as you provide the right APK path or the App Id.

You can run your iOS Tests only on Visual Studio for Mac, and for the device you need to pass the provisioning details, and as of simulator, you need to pass the Simulator Id.

If you’re using InstalledApp() or ConnectToApp() in your AppInitializer, then make sure the app is already deployed or running in the devices or simulator.

Also make sure to keep your Devices or Simulators or Emulators screens switched on at all times, otherwise tests will break giving a waiting exception.

That’s it!

But I’m not completely satisfied with the architecture, so let’s kick it up a notch! 😀

Little cherry on top Architecture!

Like I said before there’s many ways to construct the architecture for your Test project, one of my favourite ways is by separating the test cases by Page Scenario, which I think is a much cleaner structure.

We’re going to create a base class, “TestBase” which has the constructor initiation and BeforeEachTest setup, then create a sub classes that inherits from it representing whatever the pages we have in the App.

It should look something like this!

And don’t forget you need to add TestFixture attribute for every single sub-class!

So what you’re gonna do is take apart all the Test cases you had in one class and move them into the related pages, simply cut and paste of the methods should do! Also on top of that you could abstract another layer of shared steps that we could reuse across these Page tests. 😀

Then it should give you a clean Test output as below.

There you go, all the Tests are now nicely aligned and structured under the given Page which it associates with!

Pretty neat eh!

So this above structure of mine is somewhat more of a simplification of the Page Object Architecture which is well explained here for Xamarin.UITests: https://www.codetraveler.io/

And even in this official github sample from Xamarin uses the same similar pattern: SmartHotel.Clients.UITests

Done!

As you can see its not that hard to set up your Xamarin.Forms project with UITest once you get the basic understanding of the moving parts and keep a clear structure in your head.

Now for some of you might be experiencing some issues with Xamarin.UITest, in which case I had too when I was first starting off. Therefore I ended up writing this post sharing my experience of solving them: Getting your Xamarin UITests to actually work! So if you’re having any issues getting your Xamarin.UITests to work in Visual Studio, that post might be able to help you. 🙂

Do check out my Github repo of this post:
XAMVVM-Playground/XFWithUITest

Thus concludes my real walk-through of Xamarin.UITests with Xamarin.Forms, in which I hope you got a clear understanding of how to properly structure your project and all the moving bits and pieces that gets the job done! 😀

Share the love! 😀

Cheers!