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! 😀 ❤

Advertisements

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!

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!