How To Confirm Exit in Android with Xamarin Forms

Update – 2020-03-05

I updated the samples and snippets to include some reader feedback:

  1. Accounted for Master-Detail navigation in App.PromptToConfirmExit
  2. Provided a toast + back button confirmation alternative sample
  3. Updated sample: allow toggling between Master-Detail and Tabbed navigation; allow toggling between dialog and toast confirmation styles.

Overview

Ever hit the navigation bar back button when using an Android app and have it fully exit the app and drop you back on your home screen? I think all Android users have encountered this a few times. It is a frustrating and counter-productive experience. Let’s make sure your app has better UX by using a simple confirmation dialog!

Xamarin Forms Android Exit Confirmation

Good news, this is easy to implement and should only take you a few minutes to code and test.

Step 1

Create a property to check if there are pages on your navigation stack. Here’s my implementation:

Step 2

Override the OnBackPressed method in your app’s MainActivity to intercept back navigation. Here’s a sample:

We’re Done!

Wasn’t that easy! Let me know how this works out for your app. Check out my full Xamarin Forms Android Exit Confirmation sample on Github.

Implementing MSAL + AAD B2C in Xamarin – 6 Tips, Tricks and Facts

Inspired by Steven Thewissen’s excellent MSAL article, I thought I would share what I have learned about MSAL over the 3+ years I have worked with MSAL and Xamarin. If you’re just getting started, be sure to read Steven’s article, he does a great job covering how to use the tools. This article is a collection of my personal learnings and experience using MSAL in my apps.

Without further ado, here are 6 tips/tricks/facts about MSAL, AAD B2C and Xamarin:

  1. TIP: Careful with package upgrades!
    • I cannot emphasize how important this is, check out the older packages in nuget: https://www.nuget.org/packages/Microsoft.Identity.Client/ the library was in preview for nearly 3 years and I went through the pain of dealing with api changes and behaviour changes. Read the change log carefully!
  2. FACT: You cannot change the Android webview title from “Sign In” without a custom MSAL build.
  3. TRICK: Use a JWT parser to check your token expiry, if the token is expired, you can pro-actively refresh it avoiding a round trip.
  4. TIP: Android devices with older system browsers may have issues loading the sign in webview.
  5. TRICK: Careful with exceptions
  6. TIP: You don’t need your own code to save tokens to secure storage, MSAL does this for you!

My Implementation

This is roughly what I have used in my last few projects, not exact, I generally use dependency injection and a few other bits. For simplicity’s sake this is a self-contained sample implementation. I would advise using Lazy<T> for IPublicClientApplication at the very least in a real life application.

Note: The Secrets class is generated by Dan Siegel’s excellent mobile build tools.

Your thoughts?

Please let me know your thoughts, tweet at me @dylbot9000. Happy to hear good/bad/ugly/criticisms/suggestions.

Mobile Blazor Bindings – Getting Started + Why You Should Care

TLDR: The Experimental Mobile Blazor Bindings can result in much less XAML and C#, 64% less in my experiment, but the tech isn’t quite ready for prime time.

Update – 2020-02-24

I migrated my sample to the Mobile Blazor Bindings February Preview 2 Update. It only took a few minutes and fixed the issues I had previously documented and reported!

What are Mobile Blazor Bindings?

First off, Blazor is a new technology within ASP.NET Core which allows rich web applications to be written with C# instead of javascript (for the mostpart). My intent here isn’t to explain Blazor, if you wish to learn more, check out the resources listed at the end of this article.

Blazor uses the ASP.NET Razor template engine to deliver html content to browser clients. Html is markup, Xaml is markup…why not use the Razor engine to build Xamarin?

That’s the question Eilon Lipton answered with Mobile Blazor Bindings. In essence, this approach uses Razor syntax with Xamarin Forms Xaml to create mobile apps.

You may find yourself wondering why you should care…as I did when this was announced. I’m not a massive fan of Razor pages and lately I’m finding myself frustrated with the huge amount of Xaml code required to do some relatively simple things in Xamarin Forms. The Mobile Blazor Bindings approach doesn’t really solve the Razor pages issue, but it certainly helps simplify Xaml and at the same time, it also helps simplify your C# by using a binding which doesn’t rely on INotifyPropertyChanged.

Getting Started with Mobile Blazor Bindings

  1. Install Visual Studio 2019 or Visual Studio for Mac and install Xamarin
  2. Download and install .NET Core 3.0 or 3.1 SDK
  3. Install the Mobile Blazor Bindings project templates: dotnet new -i Microsoft.MobileBlazorBindings.Templates::0.1.173-beta
  4. Create a new project: dotnet new mobileblazorbindings -o FirstMobileBlazorBindingsApp
  5. This will create a FirstMobileBlazorBindingsApp folder containing a solution and 3 projects:
    1. FirstMobileBlazorBindingsApp – .NET Standard 2.0 library containing Razor templates and cross platform code
    2. FirstMobileBlazorBindingsApp.Android – Xamarin.Android head project.
    3. FirstMobileBlazorBindingsApp.iOS – Xamarin.iOS head project.
  6. Open the solution in Visual Studio
  7. Run the Android project

Note: I had no luck with iOS, I would stick to Android for now.

Check out the official documentation for Mobile Blazor Bindings and the Github repo for Mobile Blazor Bindings. Be sure to log issues with a sample solution if you run across bugs.

Porting a Xamarin Forms MVVM screen

Let’s look at an example. Since everyone’s likely here for Xamarin, we’ll start with an options selection screen I built using Xamarin Forms and MVVM.

Xamarin Forms MVVM (188 lines)

Blazor Mobile Bindings (68 lines)

120 fewer lines for the Blazor Mobile Bindings approach. Wow. I am sold.

Check out my two solutions on Github.

Conclusion

I was not excited about this approach until I actually saw the results. There is huge upside and promise, I’m looking forward to seeing where this goes. No having to worry about INotifyPropertyChanged, no commanding, far more flexibility in Xaml with the tried and true Razor engine.

On the other side, I ran into 3 relatively major issues.

  1. OnClick methods would only fire once
  2. An IsVisible flag set by a variable wasn’t working at all
  3. iOS wouldn’t work (I didn’t look very close at this).

Note: these issues are all fixed in the Preview 2 update!

There is also no hot reload support at this point, which you miss very fast after getting used to it.

Great job by Eilon Lipton and everyone else from the Xamarin and Blazor teams who brought this experiment to life!

Opening urls from xaml

I generally use Xamarin Forms to build apps. I’m currently working on a new project and using all the new greatness from Prism. One of those great features is Xaml Navigation. This is a fancy markup extension which allows you to navigate to another page in your app without implementing anything in your view models! It’s super terse and it works with xaml hot reload!

Before markup extensions

View:

<Button Text="My Account" Command="{Binding MyAccountCommand}"/>

ViewModel:

public DelegateCommand MyAccountCommand => new DelegateCommand(() => NavigationService.NavigateTo('MyAccountPage'));

After markup extensions

View (Look ma’, no ViewModel):

<Button Text="My Account" Command="{prism:NavigateTo 'MyAccountPage')"/>

How about urls?

Inspired by this, I set out to build my own xaml markup extension for opening urls in the system browser.

Before markup extensions

View:

<Button Text="Microsoft Learn" Command="{Binding MicrosoftLearnCommand}"/>

ViewModel:

public DelegateCommand MyAccountCommand => new DelegateCommand(() => Launcher.OpenAsync("https://docs.microsoft.com/en-ca/learn/"));

After markup extensions

View (I don’t have another quip for the lack of a ViewModel):

<Button Text="Microsoft Learn" Command="{extensions:OpenBrowser 'https://docs.microsoft.com/en-ca/learn/'}"/>

or use a binding:

<Button Text="Microsoft Learn" Command="{extensions:OpenBrowser}" CommandParameter="{Binding MicrosoftLearnUrl}"/>
xaml markup extensions…they’re magic

The Implementation

Check out my XamlOpenUrl sample xaml markup extension code on github and let me know your thoughts!

Xamarin Saturday 2019

Well, this post is slightly overdue…TO Mobile Devs hosted Xamarin Saturday 2019 back on August 24th, 2019, seems like a lifetime ago!

All the Toronto Xamarin Saturday 2019 sessions can be seen on YouTube!

David Ortinau opened the morning and afternoon, everyone was in the main room for these talks. The morning topic was Comet, a new Xamarin based MVU UI Toolkit being developed by the Xamarin team and primarily led by James Clancey. I see a bright future for Comet! (More to come on this in a future post…)

The group then split off, with the majority watching the lectures in the main room while Daniel Causer and I led a Xamarin 101 Workshop in another area. In the end, we helped 15 developers build their first mobile app and release it through App Center!

Andrew Park and Emily Stanek worked hard coordinating the event and to keep the stream going and interact with the online participants. The TO Mobile Devs organizers worked tirelessly leading up to the event, trying to get as much done with as little cash as possible. Thanks BSI Labs for funding the food, stickers, prizes and providing the venue!

Our speakers graciously dedicated time, effort and their own funds to get to Toronto, stay in hotels, etc. I cannot thank everyone enough.

Thank you again to our fantastic lineup:

Overall the event was a huge success! Getting 50 people to show up for an event on a Saturday in the middle of August is quite the accomplishment.

We are planning the next Xamarin Saturday for spring 2020, stay tuned!

Xamarin Saturday

Next Saturday in Toronto is Xamarin Saturday!

In case you haven’t heard, the Toronto Mobile .NET Developers group is hosting a full-day session, Xamarin Saturday, on August 24th at BSI Labs. Whether you are totally new to Xamarin or are an experienced Xamarin expert, we will have something for everyone!

Xamarin Saturday – August 24th, 2019 at BSI Labs Toronto

We will have an incredible line-up of speakers:

  • Allan Ritchie
  • Andres Pineda
  • Andrew Hoefling
  • David Ortinau
  • Mark Arteaga
  • Martin Finkel

For more information, check out the Xamarin Saturday schedule.

Additionally, if you are new to Xamarin, you can join us on Tuesday (August 20th) at 6pm at BSI Labs for a hands-on session for setting up your development environment so you can maximize your learning experience in Xamarin Saturday’s Xamarin 101 workshop.

If you’re joining us, please RSVP to the Xamarin Saturday event on Meetup. We hope to see you next weekend!

iOS 13 TestFlight Screenshot Feedback

I am often more irritated than pleased by Apple’s announcements. The notch, features that have been in Android for years being lauded as a revolutionary innovation, dropping the headphone jack…I could go on, but it would be exhausting for both of us. I think it’s important to know what I think about Apple before I move on to discussing this new TestFlight feature.

I believe TestFlight Screenshot Feedback will end up being one of the most important announcements Apple has made in the past 5 years.

What is it?

Here’s a quick demo of the new TestFlight Feedback using RateTheMeet:

Feedback is available to developers almost instantly through App Store Connect.

https://developer.apple.com/app-store-connect/whats-new/?id=testerfeedback

Testers can now send feedback directly from your beta app simply by taking a screenshot and share detailed feedback with a crash report immediately after a crash occurs. TestFlight 2.3 and iOS 13 beta or later are required. You can view and manage tester feedback in App Store Connect.
Visit your app’s TestFlight page and click Crashes or Screenshots in the Feedback section in the left side navigation. You can filter your feedback view by build numbers, app versions, devices, iOS versions, or tester groups.
For details on how testers submit feedback, see Testing Apps with TestFlight.
For details on viewing and managing tester feedback, see View tester feedback.

Why is it important?

I hope you immediately see why I’m excited about this feature. Managing feedback from users is never a simple task. Since there was no first party flow for collecting feedback on iOS or Android, this was always some sort of custom process. Whether you would do this using a third party tool or an ad-hoc flow like email or an issue tracking system, it would be a hassle for both users and developers to manage feedback.

A first party flow from Apple means that Google Play will likely work to add similar functionality in the near future. It also means I will be driving the majority of my testing through App Store connect and recommending my clients do the same.

Providing an out-of-the-box first party solution for managing feedback will help increase app quality and reduce time spent implementing third-party solutions or handling cumbersome manual feedback mechanisms. Kudos to Apple for leading the way on this important ecosystem improvement!

Xamarin Developer Summit

TLDR: This is going to be an excellent conference that you don’t want to miss! If you buy a Xamarin Developer Summit ticket within the next 24 hours, you will get a complimentary night at the The Woodlands Waterway Marriott Hotel & Convention Center.

The New Evolve

Since Microsoft purchased Xamarin and ended Xamarin Evolve, there’s been a void in the community. There has been no conference for us to gather, network, learn, share and grow. That was the void Dan Siegel was aiming to fill when he created the @XamDevSummit account and sent out this tweet back in January:

Well, it’s rapidly approaching Xamarin Developer Summit, 2 weeks until the event kicks off! Personally, I’m very excited:

Community

Since founding the Toronto Mobile .NET Developers Group back in May of 2017, I have had the pleasure of interacting with the local Xamarin community. You may not have that luxury. Xamarin Developer Summit would be a great opportunity to interact with mobile developers, build friendships, collaborate and explore ideas.

Houston: Space City

In addition to all the fantastic opportunities of the conference, I’m also looking forward to checking out Houston! I’ll be aiming to get to Space Center Houston as soon as I get a chance. I’m also going to be eating as much local food as possible: chicken-fried steak, Texas BBQ and crawfish!

Mmm, steak.

I hope to see you there!

Distributing Apps For Testing

When testing apps, I generally use a combination of 3 tools for distribution. It’s important to understand the strengths and weaknesses of the various available tools to easily onboard testers and gather feedback.

App Center

I’ll only be touching on App Center Distribute, none of the other features. I would say that it’s worthwhile to use Microsoft App Center for the distribution features alone. There are other valuable features in the App Center product which I will likely cover in future articles.

App Center Releases

App Center Distribute is overall a fantastic, robust tool for distribution. It’s great for small test groups and power users.

  • Audience:
    • Internal QA teams
    • Internal stakeholders
    • Small groups of external testers
    • iOS (and iPadOS – sigh) and Android
  • Pros:
    • Free, don’t need Apple’s blessing to push out changes
    • Android apps are extremely easy to manage
    • Multiple versions available to test at the same time (this is big)
  • Cons:
    • Uses iOS ad-hoc distribution. This means all devices you want to use to test need to be registered through Apple, and the app is packaged with a list of the registered devices and on install iOS checks to make sure the device you’re installing to is on the list. Even though you can register devices and re-package apps through App Center (really fastlane under the hood), it’s still a cumbersome process that involves manual steps from testers and admins/developers.
    • Android users need to toggle the “Allow installation of apps from unknown sources” option in settings.

TestFlight (iOS only)

TestFlight was once an independent startup working to tackle the problem of distributing apps for both Android and iOS. Apple purchased TestFlight in early 2014 and quickly removed Android support.

  • Audience:
    • iPhone/iPad users
    • Large test groups
    • Public beta testers
  • Pros:
    • Good end-user experience, simple to install test apps
  • Cons
    • Requires a separate TestFlight app
    • App approval required for beta testing
    • Can only test one version at a time
    • Builds expire after 90 days

Google Play Store (Android only)

The Google Play Store added testing distribution quite some time ago and has continued to mature the workflow.

  • Audience:
    • Android users
    • Large test groups
    • Public beta testers
  • Pros:
    • Test apps are installed through the Google Play Store (like production)
  • Cons:
    • Can only test one version at a time
    • This might be a personal thing, but I find the Google Play Publishing portal very cumbersome to use.

Conclusion

You mileage will vary with each of these tools. I recommend starting with App Center and shifting to TestFlight and the Google Play testing tracks as you move closer to a production release.

Version Checking for Xamarin Apps

The Problem

One of the biggest differences between web apps and mobile apps is the decentralized nature of mobile apps. Instead of pushing updates into servers or the cloud, we instead push the updates through the App Store and Google Play Store where the updates are pulled down by our users.

The fact that updates are not guaranteed can create some work for us as developers, particularly when we need to make a breaking change to our backend. Ideally, we want to support backwards compatibility where we can, but it’s not always possible or realistic.

The Solution

In order to avoid frustration, a flurry of support calls and having to react to the situation, you can use a simple force update flow to inform your users that their app needs to be updated.

Before we get to the code, let’s break this down into the steps of the force update flow:

  1. The app sends a request which includes the app version to the API.
  2. The API processes the request, comparing the app’s version from the request to a minimum version defined in the API configuration.
  3. If the app’s version is less than the minimum required version, the server responds with 400 Bad Request and some information about the API version and minimum client version.
  4. The app handles the response and navigates to a modal page with more information.

You’re likely tired of my rambling, let’s get to the code!

Send The App Version to the API

We’re going to extend DelegatingHandler which we will pass to our HttpClient constructor, this allows us to intercept requests/responses and do some processing. Incidentally, this is also what HttpTracer does.

Pretty straightforward, we override SendAsync and intercept the request in our ProcessRequest method. This naming convention is borrowed from MessageProcessingHandler, another BCL class, I wasn’t able to user MessageProcessingHandler because we need our processing methods to be async. Now, I know what you’re thinking, “Dylan’s an idiot, he’s not even doing any asynchronous processing”, this is true, I’m not, but I do need it to get the response content and I want the method signatures to be consistent.

Our request is augmented to include a “client-version” header, this is defined in a common library where we keep a few pieces of code which are used in the API and the client. The version value is pulled from Xamarin.Essentials.VersionTracking. The version value is the same as you would see on the stores.

Process the Request on the API

There’s a few moving parts with this. Let’s look at this from the bottom of our dependency chain up and we’ll address registration last.

We all love our interfaces, we start by defining IVersionCheckService with two simple members.

  • PerformVersionCheck – this looks at the request headers, if we have a “client-version” header specified and it’s less than the MinimumClientVersion defined in our config, we throw a ClientVersionNotSupportedException.
  • MinimumClientVersion – this exposes the configuration value for usage elsewhere if required.

Now we call our VersionCheckService from an implementation of IActionFilter, this makes it simple to decorate our controllers to specify where we’re going to enforce the version check. Note that we’re using ASP.NET Core’s build in DI which means our attribute definition looks slightly different.

Process the Response on the API

Here’s our ClientVersionNotSupportedException and our Startup registration.

There’s a bit of magic to the serializing in ClientVersionNotSupportedException to make sure we can get the information out that we need.

We’re doing a few things in Startup.cs:

  • Lines 34-36: we’re registering our configuration, service and filter.
  • Lines 42-46: we setup a custom exception handler
  • Lines: 62-71: we handle our ClientVersionNotSupportedException

Process the Response on the Client

Back to our VersionCheckHandler to handle the exception in the response.

This is our final handler, see how I have added the ProcessResponse method which takes care of deserializing our ClientVersionNotSupportedException and throwing it.

Finally, we catch the ClientVersionNotSupportedException on lines 42 & 65 and navigate to a modal page informing the user that they need to update.

Conclusion

Blogging is hard. This took a lot of time and effort, the write up started with a longer version which accounts for offline scenarios. I’ll get to that later, this is enough to digest for now.

I really hope someone finds this useful! Please let me know if you have any feedback!

The code is here if you would like to run it up: Xamarin App Version Checking