Friday, September 18, 2015

Windows 10 apps - Testing for Capabilities

Windows 10 (UWP) apps can be deployed to any device type as a single binary. But sometimes the capabilities of each device can differ. For example, a phone running Windows 10 has a Status Bar that shows network, battery and other info. But this Status Bar is missing on other devices such as the Desktop.

Let's say we add some code to hide the Status Bar in our UWP app:

                StatusBar statusBar = Windows.UI.ViewManagement.StatusBar.GetForCurrentView();

... the first thing we'll notice is that our UWP app has no idea what a Status Bar is:

  • The type name 'StatusBar' could not be found in the namespace 'Windows.UI.ViewManagement'. 

To fix this first issue, we need to add a reference to "Windows Mobile Extensions for the UWP" - which contains phone-specific capabilities...

That will make the compile happy, but what if we run this code on a Desktop or other device that doesn't have a Status Bar?

  • An exception of type 'System.TypeLoadException' occurred in MyApp.exe but was not handled in user code

    Additional information: Requested Windows Runtime type 'Windows.UI.ViewManagement.StatusBar' is not registered.
So our binary is happy to compile and run, but as you can see it will crash at runtime. To get around this, we need to test to see if the StatusBar is present on the target machine...

            if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
                StatusBar statusBar = Windows.UI.ViewManagement.StatusBar.GetForCurrentView();

So the key is the IsTypePresent method, which accepts the type name to test for. Given this, we can stick with our single binary, avoid more ugly compiler directives, and support each specific device's capabilities!