Tag Archives: Xamarin

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!

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 iOS 12 OTP Security Code AutoFill in Xamarin.Forms!

Let’s try new iOS 12 Security Code AutoFill feature in Xamarin.Forms!

The new iOS 12 update has brought a whole bunch of awesome updates, although which were mostly already was available on Android years back.

One of those features is getting rid of the old annoying OTP code filling process in iOS apps, where as every time you have to insert an OTP code into the app you have to quit the app and go to the messages and copy and past the OTP manually into the app.

But with iOS 12 update they have made it easier by allowing Apps to auto read OTP messages without going back and forth into the Message app or copy and pasting. iOS now automatically suggest the top most available OTP message in the inbox for your OTP Text fields in the Keyboard suggestion bar.

(Source: beebom.com)

Well its not practically auto-read but still much convenient than before 😉 lol

What happens is that when an OTP message receives into the Message Inbox, iOS runs a simple text matching algorithm that determines if that message is a valid OTP message or not and based on that keep a track of it in the memory, then when the user clicks on the OTP AutoFill enabled text field in an app, iOS keyboard popup that OTP as a suggestion in the keyboard. So that your users can fill up the OTP into the app without leaving the app or going back into the Messaging app. Pretty convenient!

iOS 12 update in Xamarin!

Following the new iOS 12 update, Xamarin has immediately released the support for it within weeks, so make sure to update your XCode and Xamarin nuget packs, to get your hands dirty with it!

Let’s try it in Xamarin.Forms!

Since iOS 12 is now fully supported on Xamarin, we can access those features in our Xamarin.Forms projects as well, by accessing the Xamarin native project levels. So before we get started please make sure you have updated your Xamarin iOS packages.

iOS provides a new property called UITextContentType.OneTimeCode for the TextContentType property of UITextField in Xamarin.

We’re gonna do this using a custom renderer allowing us to access the UITextField’s native properties, which is the native counterpart of Xamarin.Forms.Entry in iOS.

So let’s start by creating the Custom Control: OTPAutoFillControl

/// <summary>
/// OTP AutoFill Control for Xamarin.Forms
/// </summary>
public class OTPAutoFillControl : Entry
{

}

 

Then’ let’s createthe Custom Renderer!

[assembly: ExportRenderer(typeof(OTPAutoFillControl), typeof(OTPAutoFillControlRenderer))]
namespace XFOTPAutoFillControl.iOS
{
  public class OTPAutoFillControlRenderer: EntryRenderer
  {
    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
      base.OnElementChanged(e);

      if (e.NewElement != null)
      {
        Control.TextContentType = UITextContentType.OneTimeCode;
      }
    }
  }
}

 

There we go, setting up our Xamarin.Forms.Entry’s native counterpart UITextField for the OTP Auto-Fill feature in iOS 12.

Alright that’s it you’re all good to go.

<local:OTPAutoFillControl
	Grid.Row="2"
	FontSize="Large"
	HorizontalOptions="Center"
	Keyboard="Numeric"
	Placeholder="XXXXXX" />

 

Now use our OTPAutoFillControl anywhere in your Xamarin.Forms app, deploy to an iOS 12 Device, then retrieve an OTP message, and see the magic happens! 😉

How simple eh! 😀 yep even I was surprised at first.

Check out my github repo sample:
github.com/Xamarin-Playground/XFOTPAutoFillControl

iOS still doesn’t give out much awesome features or god-mode control of the device, but still this by far a really nice and easy to use feature from a developer’s perspective!

Few things to keep in mind!

First thing, iOS 12 – OTP Auto-Fill feature works perfectly in Xamarin Native and Xamarin.Forms because of the native magic of Xamarin. You have nothing to worry!

Then keep in mind, there’s a certain pattern of OTP messages iOS 12 supports for now, not to worry, its mostly standard ones such as below,

(Source: Apple Dev Conference WWDC 2018)

So please do keep an eye out for the OTP message structure if you run into any issues using this feature, otherwise it should work right out of the box like a charm! 😀

Now if you like to learn more about the iOS 12 developer’s update, check out their WWDC 2018 conference:

or wanna learn more of the new OTP AutoFill or Password generate in native iOS, check out these gems:

There you go!

Spread the love! 😀

Getting your Xamarin UITests to actually work! (Not thanks to Xamarin Docs)

Can’t get your Xamarin UITest to work? then this might actually help! 😉 yeah no thank you Xamarin Documentation!

Backstory?

So there I was having my Visual Studio updated to the latest version 15.8.8 and I created a fresh Xamarin.Forms project using the default template. Then I happily added the Xamarin.UITest project as well me being a TDD enthusiast.

So I wrote some code in my Xamarin.Forms project, added some pages, some simple navigation and functionality. Then I tried to run my Xamarin UITest, and surprise! I couldn’t get it to work at all.

First issue..

Everything was building nice and well, but when I tried to run the UITest, Visual Studio was annoying me with the following error in Output log.

Exception thrown: 'System.Exception' in Xamarin.UITest.dll
An exception of type 'System.Exception' occurred in Xamarin.UITest.dll but was not handled in user code
The running adb server is incompatible with the Android SDK version in use by UITest:
C:\Program Files (x86)\Android\android-sdk

You probably have multiple installations of the Android SDK and should update them or ensure that your IDE, simulator and shell all use the same instance. The ANDROID_HOME environment variable can effect this.

So I tried Debugging the UITest, and no surprise the runtime error was popping up same as above.

In utter surprise I went ahead to the Xamarin UITest documentation to see if there’s anything new that I haven’t heard before which needs to be done to get this super simple test project to run.

But nope! I had done everything as it was mentioned in the documentation with the perfect configuration in my up-to date Visual Studio and project set up already.

So what could have simply gone wrong?

After many days of researching, testing and pulling out my hair, I figured out the problem.

Xamarin.UITest version 2.2.6 (the latest to date: 26/10/2018)) does not support the latest version Android SDK Platform-Tools!

Yeah, no thank you to the Xamarin Documentation that never mentions there’s a constraint on the Xamarin.UITest supported Android SDK Platform-Tools!

Xamarin.UITest version 2.2.6 supports Android SDK Platform-Tools version 25.0.3 or lower only! (to the date: 26/10/2018))

I was actually surprised that there was no mentioning of this anywhere in the Xamarin UITest documentation! Sincerely hope they add some documentation between the support versions of Xamarin.UITest and Android SDK Platform-Tools.

Solving it!

So I went ahead and downgraded my  Android SDK Platform-Tools to version 25.0.3in my PC.

And finally got my UITest to run like a charm! 😀

Don’t you just hate it when an overhyped framework just doesn’t work as expected even after you perfectly set up everything accordingly to their documentation. 😦

Second issue..

Not only that, if you had followed the Xamarin UITest documentation and created your Xamarin.UITest project, then you may be facing the bellow error in your Error List window in Visual Studio!

This is occurring when you add the Android project reference to your Xamarin.UITest project. This actually doesn’t cause any issues on the compilation or runtime, the errors just remain there without going away.

I did a bit of digging on this issue and found out that this is a bug in Visual Studio, which has apparently been fixed in one of the previous versions in VS as Microsoft claims but its still occurring in my dev environment which has the latest version of VS 15.8.8!

Check it out here: https://github.com/MicrosoftDocs/xamarin-docs/issues/508

Since it doesn’t actually interfere in compilation or runtime, it shouldn’t really matter, but it would prevent you from adding Nuget packages to your Xamain.UITest project.

Solving it!

Simple forget what the documentation says and remove the Android project reference from your Xamain.UITest project.

There you got rid of the annoyance! 😉

Still having issues? Then these..

So if you’re still facing any issues pay attention to the following facts and give it a go!

1. Configure ANDROID_HOME environment variable in your Windows system.

Make sure you have added the User variable for ANDROID_HOME path in your Environment Variables.

2. Install the Xamarin.UITest compatible NUnit version 2.6.4 nuget in your UITest project

Make sure you have the exact version as shown above which is the NUnit version supported by Xamarin.UITest as of today.  And you’re gonna need NUnitTestAdapter verion 2.1.1 for the tests to work on Windows.

3. Make sure your AppInitializer is properly configured with apk path, or apk name.

public class AppInitializer
{
    public static IApp StartApp(Platform platform)
    {
        if (platform == Platform.Android)
        {
            return ConfigureApp.Android
                .InstalledApp("com.udara.xfwithuitest")
                .StartApp(AppDataMode.Clear);
        }

        return ConfigureApp.iOS
                .InstalledApp("com.udara.xfwithuitest")
                .StartApp(AppDataMode.Clear);
    }
}

 

There are several ways to configure your APK or IPA file, either with the name or the full file path. Make sure you have chosen best way possible for you. Above is how I have configured mine, which depends on the already installed APK or the IPA file in the device.

4. Don’t forget to configure Calabash to run the UITest for iOS

This is essential if you’re trying to get it to run on iOS, just in case if you had missed this, this is also mentioned in the documentation.

Hope that helped!

Here are some good resources if you’re getting started:

Spread the love! Cheers! 😀

XFHACKS-009 Frame with Border Image!

Ever wanted to have a Xamarin.Forms.Frame with a Border Image? Or have a Border Image around any of your Xamarin.Forms Elements? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

The Xamarin.Forms.Frame by default only has a boring BorderColor property without even letting you to set the Width of the Border or even set an Image as the Border.

So I thought of making use of my own crazy imagination and hack my way around to get this to work right from Xamarin.Forms itself!

No custom renderers, no platform specific code and no third party libraries! Just by using pure out of the box Xamarin.Forms! 😉

Sneak Peak!

That’s what we gonna be build yol! A Frame with a Border Image property along with the Border Width! 😉

XFHACKS Recipe!

Buckle up fellas, its recipe time! 😉 I’ve been writing quite a few hacks around Xamarin.Forms Frame element, and this recipe is also going to be based on my previous posts, XFHACKS-007 Frame with a Border Width! I would rather recommend you read up on that before continuing here, regardless I would explain the same concept in short here as well. Basically we’re placing a Frame element (child) inside another Frame element (parent) with a Margin value which will create visually a single frame with a Border as our choice of the Margin.

Now keeping that in mind for our Border Image we’re simply going to add Grid into the parent Frame and place an Image in it, while using the IsClippedToBounds=”True” property in both parent Frame and Grid Layout to avoid the Image element rendering itself outside the bounds of the parent Frame. Then on top of that Image inside the same Grid we’re placing our child Frame that I mentioned before with the Margin property that renders the Border aspect of the whole view.

Just like that you get the entire custom element put together which you could use as a single Frame element with a Border Image! 😉

Code!

Behold the golden XAML code!

<!--  Frame with Border Image  -->
<Frame
    Padding="0"
    CornerRadius="7"
    HasShadow="False"
    IsClippedToBounds="True">
    <Grid HeightRequest="50" IsClippedToBounds="True">
        <Image Aspect="AspectFill" 
            Source="{extensions:ImageResource   
            XFHacks.Resources.abstractbackground1.jpg}" />
        <Frame
            Margin="5"
            Padding="0"
            BackgroundColor="White"
            CornerRadius="5"
            HasShadow="False"
            IsClippedToBounds="True">
            <!--
                Whatever the content you want to
                place inside the Frame goes in here
            -->
        </Frame>
    </Grid>
</Frame>

 

There you have the Frame with Border Image in XAML just like I explained earlier. We have the parent Frame with IsClippedToBounds and CornerRadius property, the Grid and the Image with form the Border Image. Notice the Padding=”0″, since we want the Image with the Grid to spread across the parent Frame. You could change the CornerRadius as you wish to control the curved corner of the Frame.

I have given a HeightRequest value to the Grid just to make sure it renders to the exact size I need, or you could even let the whole element freely size itself according to the Element inside the whole custom Frame.  Then on top of that we have the child Frame with the Margin property cropping our the center of the Image element that’s placed under it, thus forming the Border Image as we wanted! 😀

Now let’s put it together and build something awesome! 😀

Fire it up!

Let me showcase the awesomeness of this with something fun!

 

There you go! 😀 Running side by side Android, iOS and UWP.

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

XFHACKS-008 Label with Border and Background!

Ever wanted to have a Xamarin.Forms.Label, with a Border, or even better with a Background, or with a Corner Radius customization? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

By default Xamarin.Forms.Label doesn’t have a Border, Background neither a Corner Radius property, the only possible way to achieve that is by resorting to custom renderers. So I thought of making use of my own crazy imagination and hack my way around to get this to work right from Xamarin.Forms itself!

No custom renderers, no platform specific code and no third party libraries! Just by using pure out of the box Xamarin.Forms! 😉

Sneak Peak!

That’s what we gonna be build yol!

A Label with a Border and a Background, none other than with Corner Radius customization, a true dream come true for Xamarin.Forms developers! lol kidding! 😉

XFHACKS Recipe!

Buckle up fellas, its recipe time! 😉 Now this hack basically has mostly to do with my previous post, XFHACKS-007 Frame with a Border Width! If you would like to read more on detail about it then please check that article and come back here, but let me explain it in short form here though. Basically we’re placing a Frame element inside another Frame element with a Margin value which will create visually a single frame with a Border as our choice of the Margin.

Now for our Label, we’re going to place it inside that custom Frame we just built, giving it a nicely rendered border around it. You have the complete control over the Border Width property as explained in my previous article.

And the best part of it is that this Frame will resize itself according to the Label inside of it, since we’re not restricting it to any static values, whatever the Height or Width property you set to the Label, the border will follow it. Talking of Alignment of the Label you can freely use the Margin, HorizontalOptions and VerticalOptions to easily align the Label inside the Border. 😉

Code!

Behold the golden XAML code!

<!--  Label with a Border  -->
<Frame
    Padding="0"
    BackgroundColor="#2196F3"
    CornerRadius="7"
    HasShadow="False">
    <Frame
        Margin="2"
        Padding="5"
        BackgroundColor="White"
        CornerRadius="5"
        HasShadow="False">
        <Label
            BackgroundColor="Transparent"
            HorizontalOptions="Center"
            Text="Border with curved corners"
            TextColor="Black" />
    </Frame>
</Frame>

 

There you have the Label with a Border in XAML! Just like I explained above the two Frames rendering the Border around it. Feel free to change the Margin value of the child Frame element to increase or decrease the Border-Width. And both Frames CornerRadius are used to give a curved corners effect to the Border. Let’s see it in actions:

If you want to have curved sides for the Label Border, then simply increase the CornerRadius=”16″ parent Frame and CornerRadius=”14″ for the child Frame.

Now Imagine if you want to Align the Label inside the Border, then simply use the HorizontalOptions property as you wish, for example HorizontalOptions=”Start” and just to avoid the Label crashing with the border use the Margin property of the Label in whichever the direction you’re aligning your Label to, as an example Margin=”5,0,0,0″

How about that Background I promised earlier, well then simply set the child Frame’s background Color as you wish, and if you prefer to have a different Color for Border and Background, just make sure to set different colors to parent Frame’s Background color and child Frame’s background color.

Now how about having a Background Image, what you need to do is simply add an Image behind the Label using a Grid Layout by laying down both the elements on top of each other.

<!--  Label with a Background  -->
<Frame
    Padding="0"
    BackgroundColor="#2196F3"
    CornerRadius="7"
    HasShadow="False">
    <Frame
        Margin="2"
        Padding="0"
        BackgroundColor="White"
        CornerRadius="5"
        IsClippedToBounds="True"
        HasShadow="False">
        <Grid HeightRequest="30" IsClippedToBounds="True">
            <Image Aspect="AspectFill" Source="{extensions:ImageResource XFHacks.Resources.abstractbackground.jpg}" />
            <Label
                BackgroundColor="Transparent"
                FontAttributes="Bold"
                HorizontalOptions="Center"
                Text="With a Cool Background!"
                TextColor="White"
                VerticalOptions="Center" />
        </Grid>
    </Frame>
</Frame>

 

There you have it, the golden XAML! So what we have done here is basically the same concept but with a bit more icing on top, by removing the padding inside the child Frame allowing the Image background to stretch to on to the edge of the border. Then inside the child Frame we have a Grid Layout, and its got a HeightRequest property which determines the Height of the Label, meanwhile cropping out using IsClippedToBounds property, the excessive rendering of the Image inside that’s acting as the Background.

Now let’s put it together and fire it up! 😉

Fire it up!

Load your cannons, fire it up!

 

There you go! 😀 Running side by side Android, iOS and UWP.

A little Trick! 😉

Just like how I’ve implemented the Border and Background for the Label element, you could follow the same pattern and use this for any UI Element in Xamarin.Forms as you wish, such as Image, Editor, Slider, ListView, etc whichever you wish! 😉 Just replace that Label with the UI element of your choice! 😀

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

XFHACKS-007 Frame with a Border Width!

Ever wanted to have a Xamarin.Forms.Frame with a Border which you can customize the Border-Width property? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

The Xamarin.Forms.Frame control is such a nice and useful UI element. One of the nicest features of it is the Border property, that draws a border around the View. But by default Xamarin.Forms doesn’t allow you to customize it, except for the BorderColor property, it is missing a very much needed property that even I personally wish if it had, that is the “Border Widthproperty, so that we can renderer a nice Border around the Frame as whatever the thickness we wish.

So I thought of making use of my own crazy imagination and hack my way around to get this to work right from Xamarin.Forms itself!

No custom renderers, no platform specific code and no third party libraries! Just by using pure out of the box Xamarin.Forms! 😉

Sneak Peak!

That’s what we gonna be build yol! A Frame control with a Border Width property!

XFHACKS Recipe!

Buckle up fellas, its recipe time! 😉 So the idea here is to simply, build a custom control by adding a Frame Element inside of another Frame Element, like a View parent-child relationship, and giving some Margin property values to the child Frame, which creates a border-like visual around the child Frame, by the parent Frame. Here we can set the background color of the parent Frame as we wish, which will be rendered as the Border around the Frame, and the Margin property of the child Frame will determine the Width of the visible Border. So obviously since we need to push the child’s Frame throughout the panel of parent’s we’re setting the parent Frame’s Padding to zero. Then whatever the CornerRadius we want to set for our custom Frame will always be in a manner that the child Frame’s CornerRadius will be two points less than the parent Frame’s CornerRadius, this is to maintain the nice curved corner radius of the whole custom Frame once the border is rendered.

Also if you need to maintain the HasShadow feature for our custom Frame then you should only set it for the parent Frame, not the child Frame, and since we’re using our own custom built Border we are not going to be using the default BorderColor property of any of the Frames.

Code!

Behold the golden XAML code!

<!--  Frame with a Border Width  -->
<Frame
    Padding="0"
    BackgroundColor="#2196F3"
    CornerRadius="7"
    HasShadow="False">
    <Frame
        Margin="1"
        BackgroundColor="White"
        CornerRadius="5"
        HasShadow="False">
        <!--
            Whatever the content you want to
            place inside the Frame goes in here
        -->
    </Frame>
</Frame>

There we go, just like I explained the parent and child Frame positioned accordingly with the appropriate properties. Notice how I have set the Margin=”1″, which determines the Border Thickness or the Border Width, like I explained before.

Now you are ready to use our custom Frame with Border-Width just like you would as another Frame in Xamarin.Forms! Just place whatever the content you want to put inside the custom frame inside that child Frame as commented in the code snippet! 😉

Now let’s build something fun and fire it up! 😉

Fire it up!

Let me showcase the awesomeness of this with something fun, by comparing it with a default Xamarin.Forms Frame, and the coolness of being able to customize the Border-Width of a Frame! 😉

There you go, completely identical to the default Frame but packed with awesomeness!

Alright load your canons, fire it up!

   

Alright there you have it running on Android, iOS and UWP side by side! 😀

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

XFHACKS-006 Password Entry with show/hide Text feature!

Ever wished if your Xamarin.Forms Password Entry control had the option to reveal, or show the Password text that the User types on demand, instead of the black dots? 😉  Even better, without any Custom Renderers or Platform Specific code? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

So in Xamarin.Forms to enable this feature usually you need to resort to creating Custom Renderers or some platform specific implementation, which is a tedious process and a complicated implementation. So I thought of making use of my own crazy imagination and hack my way around to get this to work right from Xamarin.Forms itself!

No custom renderers, no platform specific code and no third party libraries! Just by using pure out of the box Xamarin.Forms! 😉

Sneak Peak!

That’s what we gonna be build yol!

XFHACKS Recipe!

Let the recipe begin! So basically the idea here is to have two Entry elements which represents the Entry with IsPassword enabled and another Entry with IsPassword disabled, laid on top of each other inside a Grid layout. Also we’re going to switch the visibility of these two Entry controls on a Button click event which will also be laid on top of both the Entry elements, aligned to the right most corner of the whole Grid layout. Just to add some cheery to the icing, let’s have a Button with an Icon Image inside of it, which implementation I’ll be extracting from one of my previous XFHACKS articles, XFHACKS-005 Button with full control on Text and Icon! ! Give it a read if you’re curious! 😉

Since we’re maintaining two Entry elements, we need to make sure both of them have the same Text value at any point of the user’s interaction. So to make this happen we’re going use Element to Element binding in Xamarin.Forms, where as we are binding the Text field properties of both Entry controls to eachother. Thereby one Entry’s Text changes immediately reflects on the other one and so on.

Just to show some love for my architectural practices, I’m going to move the whole Button click event and the handling of the behavior logic of this control into a TriggerAction, aha! separation of concern or loosely coupled and no direct code behind dependency allowing for more re-usability! 😀

Code!

Behold the golden XAML code!

<Grid
   Grid.Row="1"
   Grid.Column="0"
   HeightRequest="45"
   HorizontalOptions="FillAndExpand"
   IsClippedToBounds="True">

   <!--  Entry Password  -->
   <Entry
      x:Name="EntryPassword"
      Grid.Row="0"
      Grid.Column="0"
      FontSize="Medium"
      IsPassword="True"
      IsVisible="True"
      Keyboard="Plain"
      Placeholder="Password"
      Text="{Binding Source={x:Reference EntryText}, Path=Text, Mode=TwoWay}" />

   <!--  Entry Text  -->
   <Entry
      x:Name="EntryText"
      Grid.Row="0"
      Grid.Column="0"
      FontSize="Medium"
      IsPassword="False"
      IsVisible="False"
      Keyboard="Plain"
      Placeholder="Password"
      Text="{Binding Source={x:Reference EntryPassword}, Path=Text, Mode=TwoWay}" />

   <!--  Button with Icon  -->
   <Grid
      Grid.Row="0"
      Grid.Column="0"
      Padding="0,0,3,0"
      HeightRequest="27"
      HorizontalOptions="End"
      IsClippedToBounds="True"
      VerticalOptions="Center"
      WidthRequest="35">

      <!--  Button Control  -->
      <Button x:Name="ShowPasswordButton" BackgroundColor="White">
         <Button.Margin>
            <OnPlatform x:TypeArguments="Thickness">
               <On Platform="Android" Value="-4,-6,-4,-6" />
               <On Platform="iOS" Value="0" />
            </OnPlatform>
         </Button.Margin>
         <Button.Triggers>
            <EventTrigger Event="Clicked">
               <triggers:ShowPasswordTriggerAction
                  EntryPasswordName="EntryPassword"
                  EntryTextName="EntryText"
                  IconImageName="ShowPasswordButtonIcon" />
            </EventTrigger>
         </Button.Triggers>
      </Button>

      <!--  Icon Image  -->
      <Image
         x:Name="ShowPasswordButtonIcon"
         HeightRequest="25"
         HorizontalOptions="Fill"
         InputTransparent="True"
         Source="{extensions:ImageResource XFHacks.Resources.showpasswordicon.png}"
         VerticalOptions="Fill"
         WidthRequest="25" />
   </Grid>

</Grid>

 

Here we go, explanation time! So the two Entry elements are laying on top of each other and bound to each other’s Text properties, while having one Entry as IsPassword=true and the other opposite. I have given names for the Elements because we need references of them to handle the behaviour inside our TriggerAction which I will show next.

Then the Button with the Icon Image Element is aligned to the very right corner of Parent layout, laying on top of both Entry elements. I have added some padding to it to avoid it conflicting with the border of the Entry in iOS and UWP, then for Android it shouldn’t really matter visually. There’s a HeightRequest=”27″ and WidthRequest=”35″ given to this Element group because I needed to have some horizontal space besides the Image icon visually. For the Image we’re using a EmbeddedResource type image, which makes things really easy for managing the Images.

Then for the Parent Grid Layout that holds all of these Elements together,is using IsClippedToBounds property to make sure everything holds inside the Bounds of the Grid as a single UI Element.

This is the most crucial part where inside the Button click event we’re invoking a TrigerAction called ShowPasswordTriggerAction which handles all the logic and behaviour of this custom control. And we’re passing in the names of the Elements we have assigned, into the Trigger so that we can look it up inside the TriggerAction, retrieve their runtime references and handle the behavior as we need. Pretty straightforward implementation there 😉

Next let’s look into the golden TriggerAction!

/// <summary>
/// The Trigger Action that will handle
/// the Show/Hide Passeword text
/// </summary>
public class ShowPasswordTriggerAction : TriggerAction<Button>
{
    public string IconImageName { get; set; }

    public string EntryPasswordName { get; set; }

    public string EntryTextName { get; set; }

    protected override void Invoke(Button sender)
    {
        // get the runtime references 
        // for our Elements from our custom control
        var imageIconView = ((Grid) sender.Parent)
                  .FindByName<Image>(IconImageName);
        var entryPasswordView = ((Grid) ((Grid) sender.Parent).Parent).FindByName<Entry>(EntryPasswordName);
        var entryTextView = ((Grid)((Grid)sender.Parent).Parent).FindByName<Entry>(EntryTextName);

        // Switch visibility of Password 
        // Entry field and Text Entry fields
        entryPasswordView.IsVisible =     
                       !entryPasswordView.IsVisible;
        entryTextView.IsVisible = 
                       !entryTextView.IsVisible;

        // update the Show/Hide button Icon states 
        if (entryPasswordView.IsVisible)
        {
            // Password is not Visible state
            imageIconView.Source = ImageSource.FromResource(
                "XFHacks.Resources.showpasswordicon.png",
                Assembly.GetExecutingAssembly());

            // Setting up Entry curser focus
            entryPasswordView.Focus();
            entryPasswordView.Text = entryTextView.Text;
        }
        else
        {
            // Password is Visible state
            imageIconView.Source = ImageSource.FromResource(
                "XFHacks.Resources.hidepasswordicon.png",
                Assembly.GetExecutingAssembly());

            // Setting up Entry curser focus
            entryTextView.Focus();
            entryTextView.Text = entryPasswordView.Text;
        }
    }
}

 

Here’s the most important bit where we’re handling the behaviour logic of our awesome Password Entry Control! At the moment of Invoking the Button click we’re doing a simple FindByName<T> look up for our required Elements, that are the EntryPassword field, EntryText field, and the IconImage.

First of all we’re setting the visibility of the two Entry Elements opposite for each other, as in if the User clicks on Show Password state, then the Entry with Text property will be displayed, and the user clicks on Hide Password state then the Entry with Password property (black dots) will be displayed.

Then based on the state, we’re updating the button icon’s Image source, as you can see we’re setting the showpasswordicon.png and hidepasswordicon.png respectively depending on the current state.

Finally we’re doing something extra to make sure whatever the visible the Entry element is still on Focus after the switching of the Password visibility state.

There we go, pretty straight forward yeah!

 Important: You could also move that whole piece of XAML to a separate XAML file, so that you could set it up as a reusable Control in your project! 😉

Fire it up!

Alright let’s see this in action!

 

There you have it running on Android, iOS and UWP like a charm! 😀

NO CUSTOM RENDERERS! NO NATIVE CODE! MORE AWESOME! xD

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

Improvement suggestion: I was discussing this with one of my colleagues and he pointed out an awesome tweak for a much better improvement, that is to use the same implementation with trigger and all but with a single Entry element with the IsPassword true and false state on demand instead of using two Entry elements. This is a great idea yet so simple, which will drastically improve the rendering performance. So if you wanna give it a crack please go ahead! And here’s a shout out to an awesome developer Akshay Kulkarni – ak47akshaykulkarnimake sure to check out his Github repo! 😉