Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

Xamarin Development with Visual Studio 2017 Version 15.5

Normally I don’t bother posting anything about the progressive updates that roll out for Visual Studio 2017 but version 15.5 adds a bunch of new features that are set to make app development using Xamarin just that little bit nicer. Pierce has a great post covering a lot of the relevant updates - https://blog.xamarin.com/whats-new-visual-studio-2017-version-15-5/ 

Over the last 6-12 months the debugging experience for Xamarin applications on both iOS and Android has got significantly better. I posted recently about my discovery that the Google Android emulator was actually quite good (https://nicksnettravels.builttoroam.com/post/2017/10/11/Hey-who-moved-my…-Visual-Studio-Emulator-for-Android.aspx), and whilst the build and deploy process is still painfully slow on Android, it’s definitely getting better. Now with Live XAML Previewing supported in the emulator, at least the iteration whilst making UI changes will be quicker.

I’ve also been using the remote iOS simulator – particularly at home where I use a remote build server that is on the other side of the room, it’s painful to have to deploy to a real device. I have seen some issues where debugging with the remote iOS simulator seems to just lock up but I think that was only an issue in the preview of VS mixed with the latest Windows Insider build (unfortunately neither team seems to care much about stability with their preview builds Sad smile).

Whilst I’m talking about doing iOS development, the other significant improvement in 15.5 is the messaging regarding connecting to the Mac build agent. In the past this has been limited to success/fail; if you wanted any more details you really had to go hunting in the log files (usually it ended up being a result of a mis-match of SDK versions between the build agent machine and the machine with VS installed). The dialog for connecting to the Mac build agent has a nice progress information pane at the bottom that shows what step the connection manager is at and reports any issues – nice work MS, this is really, really useful!

Ok, I can’t end this post without pointing to the fact that Microsoft has finally worked out how to get the elephant out of the corner of the room, and by this I mean the support for PCLs v’s .NET Standard for new projects. Prior to this release if you created a new Xamarin project it would create a PCL for your shared code (and yes, I’m ignoring the Shared Project option, cause this should never be selected), and it was rather painful to have to upgrade it to .NET Standard (see https://nicksnettravels.builttoroam.com/post/2017/08/26/Getting-Started-Xamarin-Forms-with-NET-Standard.aspx if you’re still on an older version of Visual Studio). Now when you create a new Xamarin project you get a .NET Standard library and you can pick which target platform(s) you want to target (I would encourage you to pick all, unless you have a particular reason not to!).

Grab the latest version of Visual Studio 2017 and get coding!

Authentication Redirection Loop with Angular Application and Azure Active Directory

Recently we ran in to some difficulty with an Angular application that was being retrofitted into a different environment. During the initial development the Angular application had been pushed to Azure for testing. However, the final resting place for the application was on a on-premises sever. Whilst the switch was relatively painless, with the only major change being to a persistent file storage instead of blob storage, we also had to shift from our development Azure AD tenant (the Angular application, and the associated services, uses Azure AD to authenticate and authorize users), to the client’s Azure AD tenant. This shift required creating two new application registrations within the client’s Azure AD tenant.

Unfortunately after creating the new registrations, and updating the Angular application (and the corresponding services), any attempt to log in with valid credentials resulted in a continual loop between the Angular application and the Azure AD login prompt. In this case we were only using Azure AD to authenticate users and other than controlling access to the application services there weren’t any other permissions that users would have to agree to.

In the past I’ve posted about how administrators have to grant permission to users within their tenant to access an application (see https://nicksnettravels.builttoroam.com/post/2017/01/24/Admin-Consent-for-Permissions-in-Azure-Active-Directory.aspx). Usually there is an Azure AD login error when users attempt to sign in. In this case, for some reason we either missed the error message or it was being obscured by the automatic redirection between the Angular application and the Azure AD login prompt.

We did end up finding the solution, thanks to the Azure AD team at Microsoft, who quickly identified the error in our Fiddler trace. The critical request/response was:

Request

GET https://login.microsoftonline.com/<tenantid>/oauth2/authorize?response_type=token&client_id=<clientid>&resource=<resourceid>&redirect_uri=<uri>&prompt=none&login_hint=admin

Response

HTTP/1.1 302 Found
Location: <uri>
<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href="<uri>/#error=interaction_required&amp;error_description=AADSTS65001%3a+The+user+or+administrator+has+not+consented+to+use+the+application+with+ID+%27.+Send+an+interactive+authorization+request+for+this+user+and+resource

The important part is that the error indicates that either the user or administrator has not consented to use of the application, and that there should be an interactive authorization request. This is a little cryptic but going back to my previous post we can simply add “prompt=admin_consent” to the login request – assuming an administrator logs in, they can then grant access to the application to all users in the tenant.

There is actually a much easier way for single tenant applications, which this is. Instead of waiting for an administrator to log in, permission can be granted via the Azure portal:

- Select the Directory where the application is registered (drop down in top right cornert of the Azure portal where the signed in user is listed)

- Select Azure Active Directory from the sidebar menu

- Select App Registrations

- Select the application registration you want to grant access to

- From All settings, click on the Required Permissions link

- Click “Grant Permissions”

image

This will give all users access to the application. If you have multiple registrations (eg one for the web site and one for the corresponding services), don’t forget to grant permission to both registrations.

Again, big thanks to the team at Microsoft for pointing us to the solution

Styling the MediaPlayerElement and MediaTransportControls in a Universal Windows Platform (UWP) Application

In my previous post, Building Media Applications for the Universal Windows Platform (UWP) using the MediaPlayerElement, I covered the basics of building a UWP media application using the MediaPlayerElement. Towards the end of the post I showed how you can override some of the built in behaviour but I was yet to show you how you can adjust the visual style of the player or the controls. In this post I’ll do just that, I’ll show you where to find the built in styles and how to start customizing them, including some gotchas that you should be aware of.

Ok, let’s get started by looking for the built in styles. Whilst Microsoft now do a good job of documenting the built in styles online (for example the styles and templates for the MediaTransportControls element is defined at https://msdn.microsoft.com/en-us/library/windows/apps/mt414180.aspx), there is nothing like looking at what ships in the platform. For this we go to generic.xaml, typically located at C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.16299.0\Generic – Note that this may vary based on which platform SDK you have installed. Inside generic.xaml I’m going to locate the Style for the MediaPlayerElement:

<Style TargetType="MediaPlayerElement">
     <Setter Property="HorizontalAlignment" Value="Stretch" />
     <Setter Property="VerticalAlignment" Value="Stretch" />
     <Setter Property="IsTabStop" Value="False" />
     <Setter Property="Template">
         <Setter.Value>
             <ControlTemplate TargetType="MediaPlayerElement">
                 <Grid x:Name="LayoutRoot">
                     <Border Background="Transparent" />
                     <Image  x:Name="PosterImage"
                         Visibility="Collapsed"
                         Source="{TemplateBinding PosterSource}"
                         Stretch="{TemplateBinding Stretch}" />
                     <MediaPlayerPresenter x:Name="MediaPlayerPresenter"
                         IsFullWindow="{TemplateBinding IsFullWindow}"
                         Stretch="{TemplateBinding Stretch}"
                         MediaPlayer="{TemplateBinding MediaPlayer}" />
                     <ContentPresenter     x:Name="TransportControlsPresenter"
                         Visibility="{TemplateBinding AreTransportControlsEnabled}" />
                     <Grid x:Name="TimedTextSourcePresenter" />
                 </Grid>
             </ControlTemplate>
         </Setter.Value>
     </Setter>
</Style>

As you can see, the Style for the MediaPlayerElement is made up of a few different components:

  • MediaPlayerPresenter – this is where the actual video content will be displayed
  • ContentPresenter – this is where the player controls will be displayed
  • “TimedTextSourcePresenter” – this is where the closed captions will be presented

Let’s make a subtle change here by adding another Grid immediately after the TimedTextSourcePresenter with a semi-transparent Pink colour and a TextBlock to indicate that this is a customized player.

<Page.Resources>
     <Style TargetType="MediaPlayerElement">
         <Setter Property="HorizontalAlignment"
                 Value="Stretch" />
         <Setter Property="VerticalAlignment"
                 Value="Stretch" />
         <Setter Property="IsTabStop"
                 Value="False" />
         <Setter Property="Template">
             <Setter.Value>
                 <ControlTemplate TargetType="MediaPlayerElement">
                     <Grid x:Name="LayoutRoot">
                         <Border Background="Transparent" />
                         <Image  x:Name="PosterImage"
                                 Visibility="Collapsed"
                                 Source="{TemplateBinding PosterSource}"
                                 Stretch="{TemplateBinding Stretch}" />
                         <MediaPlayerPresenter x:Name="MediaPlayerPresenter"
                                                 IsFullWindow="{TemplateBinding IsFullWindow}"
                                                 Stretch="{TemplateBinding Stretch}"
                                                 MediaPlayer="{TemplateBinding MediaPlayer}" />
                         <ContentPresenter     x:Name="TransportControlsPresenter"
                                                 Visibility="{TemplateBinding AreTransportControlsEnabled}" />
                         <Grid x:Name="TimedTextSourcePresenter" />
                        <Grid Background="Pink"
                                 IsHitTestVisible="False"
                                 Opacity="0.4">
                             <TextBlock Foreground="Black"
                                         Text="Custom Player" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="50,5,5,5"/>
                         </Grid>

                     </Grid>
                 </ControlTemplate>
             </Setter.Value>
         </Setter>
     </Style>
<Page.Resources>

You’ll notice that I’ve added this Style into the Resources dictionary for the page and that it’s an implicit style (ie I haven’t assigned it a Key) which means that any MediaPlayerElement on this page will pick up this style. You can of course set this Style either directly on the MediaPlayerElement itself or even define it in an application level resource dictionary.

image

Note also that the IsHitTestVisible attribute is set on the Grid, otherwise it will block user input to the player controls as the grid sits over the top of the other elements within the MediaPlayerElement control template.

If you recall from my previous post I intercepted the behaviour that steps the video back and forward so that I could customize this behaviour. Of course, this means that the step forward/backward icons aren’t accurate, since I’m not longer stepping back by 10seconds and forward by 30seconds. In order to override the icons on these buttons, I need to override the Style for the MediaTransportControls. Again the default Style can be found in generic.xaml – it’s really long, so I’m not going to copy the whole thing in here. Here’s a cut down version of the Style showing the changes to the FontIcon for the SkipBackwardButton and SkipForwardButton.

<Page.Resources>
     <Style TargetType="MediaTransportControls">
     ...
         <Setter Property="Template">
             <Setter.Value>
                 <ControlTemplate TargetType="MediaTransportControls">
                     <Grid x:Name="RootGrid"
                             Background="Transparent">
             ...   
             <AppBarButton x:Name='SkipBackwardButton'
                          Style='{StaticResource AppBarButtonStyle}'
                          MediaTransportControlsHelper.DropoutOrder='5'
                          Visibility='Collapsed'>
                           <AppBarButton.Icon>
                         
  <!--<FontIcon Glyph="&#xED3C;" />-->
                            <FontIcon Glyph="&#xF100;"
                                      FontFamily="FontAwesome" />

                           </AppBarButton.Icon>
                         </AppBarButton>
                         ...
                         <AppBarButton x:Name='SkipForwardButton'
                          Style='{StaticResource AppBarButtonStyle}'
                          MediaTransportControlsHelper.DropoutOrder='5'
                          Visibility='Collapsed'>
                           <AppBarButton.Icon>
                         
  <!--<FontIcon Glyph="&#xED3D;" />-->
                            <FontIcon Glyph="&#xF101;"
                                      FontFamily="FontAwesome" />
                           </AppBarButton.Icon>

                         </AppBarButton>
                     </Grid>
                 </ControlTemplate>
             </Setter.Value>
         </Setter>
     </Style>
</Page.Resources>

You might be wondering where I got the new hex code for the FontAwesome font. Rather than go online and having to hunt down hex values for the different characters within a font, if you open Word and go to Insert, Symbol, you can then select the Font and select the character you want. In the lower right corner it states what the Character code is. Remember that you need to make sure the font exists on the computer you’re going to run the application on, so you may want to consider including the font within your application if you pick a non-standard font.

image

Ok, so running the application now, we can see the updated skip backward and skip forward buttons:

image

Unfortunately, here lies a major bug in the implementation of the MediaPlayerElement – if you press the full screen button, you’ll see that the Style for the MediaTransportControls has reverted back to the built in style.

image

This happens because when the video runs in full screen, the MediaTransportControls are being hosted in a separate visual tree to the main part of the application - you can see this if you look at the Live Visual Tree.

image

So, the question is how to handle this? Well the good news is that it’s surprisingly simple. What’s happening is that as the MediaTransportControls are being attached to a different visual tree, they’re not able to resolve the Style defined within the scope of the page. Moving the custom Style for the MediaTransportControls to an application level resource fixes this issue.

<Application
     x:Class="PlayerSample.App"
     xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     RequestedTheme="Light">
     <Application.Resources>
         <Style TargetType="MediaTransportControls">
         ...
         </Style>
     </Application.Resources>
</Application>

The documentation online at https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/custom-transport-controls indicates that you should use an explicit style – two things a) this doesn’t fix the full screen issue; you must define the Style at an application level regardless of whether you make it an explicit or implicit style and b) you can make the choice yourself whether to use an implcit or explicit style, depending on whether you want multiple different player styles (ie where an explicit style makes sense).

Building Xbox One applications with the Universal Windows Platform

When building a Universal Windows Platform application there are times when you’ll want a different layout/functionality for a particular platform. For the most part building applications across desktop and phone, other than dealing with different screen sizes and orientation, as a developer you can rely on a similar interaction model: mouce clicks and taps equate to roughly the same interaction for most applications. However, this is not the case with the Xbox – the interaction model using either the media remote or a controller relies on a focus state moving around the screen, followed by pressing the action button to select the currently focussed item. In addition to making sure that every control has an appropriate “in focus” visual, it’s essential to make sure that the flow of focus makes sense and that the user can’t get lost in the application (eg nothing focussed, or nothing appearing to be in focus, on the screen).

The different interaction model between desktop/mobile and Xbox means that you’ll often want to present a different layout, or perhaps expose different functionality on Xbox. There are a number of ways to handle this both in XAML and in code:

1. [C#] The device family can be detected using DeviceFamily property. This returns values such as Windows.Mobile, Windows.Desktop and Windows.Xbox which can be used to define business logic that may be platforms specific. Note that the family name for Surface Hub is Windows.Team

var family = Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily

2. [XAML] The device family can be used to trigger different visual states. There are a number of state triggers that have been packaged together as a NuGet package - https://github.com/dotMorten/WindowsStateTriggers.

<VisualStateManager.VisualStateGroups>
     <VisualStateGroup x:Name="PlatformStates">
            <VisualState x:Name="Xbox">
             <VisualState.Setters>
                 <Setter Target="textBlock.(TextBlock.Text)"
                         Value="Running on Xbox" />
             </VisualState.Setters>
             <VisualState.StateTriggers>
                 <WindowsStateTriggers:DeviceFamilyStateTrigger DeviceFamily="Xbox" />
             </VisualState.StateTriggers>
         </VisualState>
         … other platform states …
     </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

3. [XAML] Use different XAML files for each device family

Main.xaml  // The default XAML file

Main.DeviceFamily-Xbox.xaml  // An Xbox specific XAML file defined within the file name

/DeviceFamily-Xbox/Main.xaml // An Xbox specific XAML file defined using a folder to group together platform specific files.

Using these three different methodds might seem easy enough at first but you start to realise how frustrating it is when you want to work on a specific feature (for example navigation) but you don’t have a specific device with you (for example there’s no Xbox nearby for running the app on). To at least partial solve this problem, here are three tips that will allow you to work on your Xbox app on your desktop.

1. [C#] Instead of referencing the AnalyticsInfo class, we can add a wrapper class that allows us to override the device family whilst debugging the application. Use DeviceInfo.DeviceFamily instead of AnalyticsInfo.VersionInfo.DeviceFamily

#if DEBUG
#define DEBUG_PLATFORM_XBOX
#endif

public static class DeviceInfo
{
     public static string DeviceFamily
     {
         get
         {
#if DEBUG_PLATFORM_XBOX
             return "Windows.Xbox";
#else
             return AnalyticsInfo.VersionInfo.DeviceFamily;
#endif
         }
     }
}

In this case the compilation constant DEBUG_PLATFORM_XBOX is used to override the actual DeviceFamily value. Note we’ve wrapped this using a #if for the DEBUG constant – this prevents the override accidentally being deployed as part of a release build.

2. [XAML] The DeviceFamilyStateTrigger (see https://github.com/dotMorten/WindowsStateTriggers/blob/master/src/WindowsStateTriggers/DeviceFamilyStateTrigger.cs) uses the DeviceFamily returned by the AnalyticsInfo class. A clone of this trigger can be made that relies on DeviceInfo.DeviceFamily (from [1]); this would activate states based on the overridden device family value.

3. [XAML] In order to debug the Xbox layout (eg MainPage.DeviceFamily-Xbox.xaml) on a desktop machine, simply rename the file to specify the Desktop device family (ie MainPage.DeviceFamily-Desktop.xaml).

Combining these three tips allows for the majority of the application to look and feel like it would when running on an Xbox. Unfortunately some of the built in components do render differently on desktop and xbox – they will always render as per the actual device family, despite attempts to override this value.

Building Media Applications for the Universal Windows Platform (UWP) using the MediaPlayerElement

Over the past couple of years at Built to Roam we’ve built a number of media applications. Back when UWP was first launched, all media was played using the MediaElement, which was fairly familiar to XAML developers as it’s been the core element for any video or audio playback on Windows and Windows Phone for quite some time. Unfortunately the built in controls on the MediaElement were not easily stylable, resulting in most developers switching to using the Player Framework, which provided a host of capabilities out of the box such as closed captions, stylable regions and controls, and nice viewmodel architecture that made data binding easy.

Fast forward a year and a bit, and there’s a new player in town, literally. The MediaPlayerElement is a new control that shipped with the Anniversary update (v10.0.14393.0) and is definitely the control that you want to use if you want to do fancy things, such as a persistent video overlay where playback continues as the user continues to navigates throughout the application – this can be achieved by detaching the internal MediaPlayer from one MediaPlayerElement and attach it to another. It’s important to note that whilst the MediaPlayerElement has been around since the Anniversary update, features have been added in both the Creators update and more recently the Fall Creators update, so make sure you take a look at the documentation to make sure you are using features that align with the minimum and target versions you have set for your application.

In this post we’re going to look at the basics of using the MediaPlayerElement and how you can alter its styling. I’m going to start with a new UWP project, selecting the Creators update as the minimum version and the Fall Creators update as the target version. The MediaPlayerElement can be super simple to use – for example the following code is the simplest way to add video to a page that will automatically start playing.

<MediaPlayerElement Source="http://sample-videos.com/video/mp4/240/big_buck_bunny_240p_30mb.mp4"  AutoPlay="True"/>

By default the MediaPlayerElement doesn’t show any of the typical playback controls you’d expect, instead it’s just a raw video canvas that can be used to render video anywher on a page or control. In order to enable the default controls, you simply need to add the AreTransportControlsEnabled attribute set to true (I’ve removed the AutoPlay attribute as there are now going to be playback controls that can be used to start/stop video etc)

<MediaPlayerElement Source="http://sample-videos.com/video/mp4/240/big_buck_bunny_240p_30mb.mp4"  AreTransportControlsEnabled="True"/>

The following image shows the default controls with Progress Bar, Play/Pause, Volume, Aspect Ratio, Cast and Full screen buttons and as you’d imagine, they’re all connected to the appropriate action.

image

But what about other controls like fast forward/rewind, skip forward/backward etc. To customise what controls appear you need to override the TransportControls attribute on the MediaPlayerElement:

<MediaPlayerElement Source="http://sample-videos.com/video/mp4/240/big_buck_bunny_240p_30mb.mp4"
                     AreTransportControlsEnabled="True">
    <MediaPlayerElement.TransportControls>
         <MediaTransportControls IsSkipForwardButtonVisible="True"
                                 IsSkipBackwardEnabled="True"
                                 IsSkipBackwardButtonVisible="True"
                                 IsSkipForwardEnabled="True"
                                 IsFastForwardButtonVisible="True"
                                 IsFastForwardEnabled="True"
                                 IsFastRewindButtonVisible="True"
                                 IsFastRewindEnabled="True" />
     </MediaPlayerElement.TransportControls>

</MediaPlayerElement>

Here I’ve set the TransportControls attribute to be a new instance of the MediaTransportControls class – this is actually what the default behaviour does; the difference is that I now have access to an instance that I can set attributes on. Here I’m enabling, and showing both the buttons to skip forward/backward and the buttons for fast forward/rewind. The updated layout looks like the following:

image

As you can see from the image the skip forward and backward buttons default to 30 and 10 seconds respectively. In order to adjust these you’ll need to override the behaviour that is associated with the skip forward/backward buttons, which can be done by attaching an event handler to the PositionReceived event on the MediaPlaybackCommandManager:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
     base.OnNavigatedTo(e);

    Player.MediaPlayer.CommandManager.PositionReceived += CommandManager_PositionReceived;
}

private void CommandManager_PositionReceived(MediaPlaybackCommandManager sender, MediaPlaybackCommandManagerPositionReceivedEventArgs args)
{
     sender.MediaPlayer.PlaybackSession.Position = TimeSpan.FromMinutes(2);
     args.Handled = true;
}

In this case, I’ve named the MediaPlayerElement in the XAML (ie by adding x:Name=”Player” to the MediaPlayerElement), and then when the page has been navigated to I’m attaching the appropriate event handler. When either skip forward or backward is pressed, the position in the playback is set to the 2 minute mark and the args.Handled property is set to true, effectivey overriding the default skip behaviour. Big reminder: if you are attaching event handlers in code, make sure you detach them too (ie PositionReceived –= CommandManager_PositionReceived in the OnNavigatedFrom method).

The fast forward and fast rewind buttons will increment the playback speed up and down by doubling the rate over the range of rates supported by the content (eg –8, –4, –2, –1, 1, 2, 4, 8). The MediaTransportControls class is clever enough to detect the supported range of rates and automatically disable the fast foward/rewind buttons when the limit on the range has been reached.

Note: In working with the MediaPlayerElement, and even in preparing the sample code for this blog post, I was not able to get the fast rewind functionality to work. Fast foward appears to work but it causes the control bar to hide and show in a weird oscillating fashion. My recommendation would be to give these buttons a wide birth as this feature is severely under baked – if you want to implement something similar, perhaps with thumbnails, you should consider implementing it yourself!!! (and yes, we’ve had to do this on a project)

In this post, you’ve seen the basics of adding a MediaPlayerElment and playing some content using the built in media controls. I’ll go into more detail soon on really customising the style of your player.

Update: It seems that by setting the minimum version of the UWP application to the Fall Creators update, it appears that fast forward/rewind seems to work. I’m guessing it may have been fixed!

View Model States and Connecting them to Xamarin Forms Visual States using BuildIt

In my previous post on Getting Started with Visual States in Xamarin Forms using BuildIt.Forms I showed a very basic example of defining and triggering Visual States within a Xamarin Forms application. However, most applications have more complexity where each page is typically data bound to a corresponding ViewModel and it is the ViewModel which encapsulated the logic of the application.

Let me walk through working with a ViewModel using the same basic example I started in my previous post. In this case I’m going to add another panel to the page which will be displayed after the user clicks the Login button, effectively simulating the experience of showing a progress indicator whilst the application is authenticating the user.

<!-- Authenticating Prompt -->
<Grid BackgroundColor="LightPink"
         x:Name="AuthenticatingIndicator"
         IsVisible="false">
     <Label Text="Attempting to authenticate you..."
             HorizontalTextAlignment="Center"
             VerticalOptions="Center" />
</Grid>
<!-- END Authenticating Prompt –>

In this case I’m going to add a new VisualStateGroup to define the visual states to hide and show the AuthenticatingIndicator Grid.

<vsm:VisualStateGroup Name="AuthenticationStates">
     <vsm:VisualState Name="Authenticating">
         <vsm:VisualState.Setters>
             <vsm:Setter Element="{x:Reference AuthenticatingIndicator}"
                         Property="IsVisible"
                         Value="true" />
         </vsm:VisualState.Setters>
     </vsm:VisualState>
     <vsm:VisualState Name="NotAuthenticating" />
</vsm:VisualStateGroup>

A VisualStateGroup is designed to hold mutually exclusive states. A page can have any number of VisualStateGroups, and at any given point in time the current state of the page can consist of being in one VisualState from each group. In this scenario we have broken the authenticating states away from the loading states because in theory you might want to disply both the AuthenticatingIndicator, as well as the LoadingIndicator.

The last piece of XAML that I need to update is to attach an event handler to the Clicked event of the Button:

<Button Text="Login"
         Clicked="LoginPressed" />

And in the code behind, define the corresponding LoginPressed method (and yes, those MVVM purist will argue that this would be better using the Command property through to the ViewModel but we’ll leave that for another post):

protected async void LoginPressed(object sender, EventArgs e)
{
}

Now that we have the XAML defined, it’s time to look at how we can drive this from our ViewModel. In my case the page I’m working with is called MainPage.xaml, so I’m going to define a class called MainViewModel in a separate .NET Standard library. I’m not going to add a reference to BuildIt.Forms to the .NET Standard library because that would bring in a reference to Xamarin Forms, which should not be referenced by the library that holds your ViewModels – they should be abstracted away from any concrete interface, which includes Xamarin Forms, even though it is itself an abstraction from the native platform interfaces. What I am going to reference is the BuildIt.States library, which is a .NET Standard library that has no reference to any specific user interface framework, making it perfect for managing states within your ViewModel.

Alongside the MainViewModel class I’m also going to define an enumeration where the names match the corresponding visual states: the enum type name has to match the VisualStateGroup name and the enum values have to match the VisualState name.

public enum AuthenticationStates
{
     Base,
     Authenticating,
     NotAuthenticating
}

The enum also has an additional value, Base, which is will be the default enum value. The name of this value is irrelevant but it’s important to have it as the first value and should not correspond to any VisualState name.

The MainViewModel class includes a StateManager property. In this case the constructor calls the extension method DefineAllStates to define states for each value of the AuthenticationState enum. The BuildIt States library has a host of great features that are worth explaining but I’ll save that topic for another post. The important thing is that each of the states for the AuthenticationState enum are defined.

public class MainViewModel
{
     public IStateManager StateManager { get; } = new StateManager();

    public MainViewModel()
     {
         StateManager.Group<AuthenticationStates>().DefineAllStates();
     }

    public async Task Login()
     {
         await StateManager.GoToState(AuthenticationStates.Authenticating);

        await Task.Delay(2000);

        await StateManager.GoToState(AuthenticationStates.NotAuthenticating);
     }
}

The Login method simply calls the GoToState method prior to calling Task.Delay, to simulate attempting to authenticate the user, and then again calling GoToState to change the state back to the NotAuthenticating state.

Now that we have our MainViewModel defined, I need to connect it to my MainPage. For real applications we work on at Built to Roam, we use frameworks such as MvvmCross to connect the View and ViewModels. However, for brevity I’m going to simply create an instance of the MainViewModel as part of the MainPage:

private MainViewModel ViewModel { get; } = new MainViewModel();

And then set the instance as the BindingContext of the page, in the constructor:

public MainPage()
{
     InitializeComponent();

    BindingContext = ViewModel;
}

Lastly, I’ll update the LoginPressed method to call the method on the MainViewModel:

protected async void LoginPressed(object sender, EventArgs e)
{
     await ViewModel.Login();
}

At this point we’re almost done: We have a ViewModel that defines the states of the application in a way that they can be tested in absence of any user interface implementation, and the View (in this case the MainPage) will invoke the Login method to trigger the state changes. The only missing component is connecting the Visual States defined on the MainPage XAML, with the states defined in the MainViewModel. This is done using the Bind method within the OnAppearing override:

await VisualStateManager.Bind(this, ViewModel.StateManager);

Now I’m ready to go – at this point the user experience is entirely defined in XAML, with all my logic, including the states, encapsulated within my ViewModel, ready to be tested.

Getting Started with Visual States in Xamarin Forms using BuildIt.Forms

Over the past couple of months we’ve been working on getting the BuildIt.Forms library to a point where it was stable enough to promote and talk about. With the recent release of the 2.4 update for Xamarin Forms, we’re finally able to push out a stable release.

The BuildIt.Forms library brings with it quite a few features but probably the best reason to use the library is the support it adds for defining Visual States within your Xamarin Forms application within the XAML, just like you would if you were building using XAML for UWP (or any other XAML platform such as WPF etc). We’ve tried to stay as true as possible to the syntax for Visual States used on other platforms but like all things Xamarin Forms there are some differences that you’ll need to get your head around.

Ok, before we jump in, let’s take a back step and look at what a Visual State really is, and why you’d want to use them. Let’s start with a very simple example – imagine you have a page within your application that needs to load some data and you want to provide a visual cue that something is happening. In this case I’m going to add a simple overlay with some text indicating that information is being loaded:

<!-- Loading Prompt -->
<Grid BackgroundColor="LightGray"
         x:Name="LoadingIndicator"
         IsVisible="false">
     <Label Text="Loading..."
             HorizontalTextAlignment="Center"
             VerticalOptions="Center" />
</Grid>
<!-- END Loading Prompt –>

Note that the default IsVisible value is false, meaning that the LoadingIndicator Grid will not be visible. In the codebehind of the page I can then add code that would show the LoadingIndicator Grid, simulate loading content (ie Task.Delay), and then hide the LoadingIndicator Grid.

protected override async void OnAppearing()
{
     base.OnAppearing();

    LoadingIndicator.IsVisible = true;

    await Task.Delay(2000);

    LoadingIndicator.IsVisible = false;
}

Of course in a real application you wouldn’t do this, as there should be at least a ViewModel that would do the loading but we’ll come back to the use of ViewModels later. For the moment, it’s enough to point out that we controlling the appearance of individual elements based on the state of the page (ie showing the LoadingIndicator when the page is in the loading state). What would be great is if we could declare these states in XAML, which is where the BuildIt Forms library comes in.

I’ll add a few namespaces to the XAML for the page (mainly so I don’t forget to add them later when we talk about animations and other controls in the BuildIt Forms library):

xmlns:ctrl="clr-namespace:BuildIt.Forms.Controls;assembly=BuildIt.Forms.Controls"
xmlns:vsm="clr-namespace:BuildIt.Forms;assembly=BuildIt.Forms.Core"
xmlns:anim="clr-namespace:BuildIt.Forms.Animations;assembly=BuildIt.Forms.Core"

Next, immediately inside the root tag of the page, I’ll define two visual states:

<vsm:VisualStateManager.VisualStateGroups>
     <vsm:VisualStateGroups>
         <vsm:VisualStateGroup Name="LoadingStates">
             <vsm:VisualState Name="Loading">
                 <vsm:VisualState.Setters>
                     <vsm:Setter Element="{x:Reference LoadingIndicator}"
                                 Property="IsVisible"
                                 Value="true" />

                 </vsm:VisualState.Setters>
             </vsm:VisualState>
             <vsm:VisualState Name="Loaded" />
         </vsm:VisualStateGroup>
     </vsm:VisualStateGroups>
</vsm:VisualStateManager.VisualStateGroups>

The important things to note are the names of the states: Loading and Loaded, and the use of a Setter element to adjust the IsVisible property on the LoadingIndicator element. Note that I didn’t need to set the IsVisible property to false in the Loaded state – this is because the default value of the IsVisible property on the LoadingIndicator is set to false, and the Visual State manager is clever enough to remember that when switching between states.

Now that we have visual states defined, let’s switch to the code behind and adjust the code to use the visual states:

protected override async void OnAppearing()
{
     base.OnAppearing();
    await VisualStateManager.GoToState(this, "Loading");
    await Task.Delay(2000);
     await VisualStateManager.GoToState(this, "Loaded");
}

It looks like we haven’t made any great improvements but here’s where the power is – let’s add some content to the screen that will be shown when the loading is complete:

<!-- Login Prompt -->
<Grid x:Name="LoginPrompt"
         IsVisible="False">
     <StackLayout>
         <Label Text="Username:" />
         <Editor />
         <Label Text="Password:" />
         <Editor />
         <Button Text="Login" />
     </StackLayout>
</Grid>
<!-- END Login Prompt –>

In the past, this would have required more code in the code behind to adjust the IsVisible property on the LoginPrompt Grid in order to show the content. With visual states, there is no need to alter the logic of the application, I just need to adjust the Loaded visual state by adding a Setter to set the IsVisible property to true.

<vsm:VisualState Name="Loaded">
     <vsm:VisualState.Setters>
         <vsm:Setter Element="{x:Reference LoginPrompt}"
                     Property="IsVisible"
                     Value="true" />

     </vsm:VisualState.Setters>
</vsm:VisualState>

At the moment I have built an interface that provides useful feedback to the user about the loading state of the application. However, there is a rather abrupt change between the LoadingIndicator Grid and the LoginPrompt. It would be nice to be able to add animations to make the transition smoother. Again without adjusting the logic of the application I can do this by adding animations directly to the visual states. The following animation can be added after the Setters of the Loading state.

<vsm:VisualState.LeavingAnimations>
     <anim:AnimationGroup>
         <anim:AnimationGroup.PreAnimations>
             <anim:FadeAnimation Duration="500"
                                 Opacity="0"
                                 Element="{x:Reference LoadingIndicator}" />
         </anim:AnimationGroup.PreAnimations>
     </anim:AnimationGroup>
</vsm:VisualState.LeavingAnimations>

In this case the animation will be run prior to (ie a PreAnimation) any state change away from (ie a LeavingAnimation) the Loading state, and will fade the LoadingIndicator Grid out to 0 Opacity over a duration of 500 milliseconds.

In this post I’ve covered the basics of creating Visual States. In my next post I’ll cover using states in a ViewModel and how you can link them to the Visual States on the page to give you a more testable application.

Hey, who moved my… Visual Studio Emulator for Android?

A while ago, in response to a common frustration from Xamarin developers, Microsoft released the Visual Studio Emulator for Android and it even made it into the Visual Studio installer:

image

As a long-serving Windows Phone developer I embraced this decision as the emulator was based on Hyper-V which meant that it played nicely with the Windows Phone emulators – I could now do cross platform development, even when I didn’t have real devices with me. Unfortunately, Microsoft have indicated that the emulator is no longer going to receive updates, so anyone wanting to dev/test on more recent builds of Android are out of luck. This was really frustrating as the emulator was both quick (relative to the out of the box emulators from Google – historically) and didn’t require another emulator sub-system (as it worked on Hyper-V).

Recently, Microsoft have actively discounted Windows Phone, making it very hard to justify any developer resources on building for Windows Phone…. it also makes me question the value proposition of UWP over WPF, but that’s a topic for a different post. The upshot is that there is no longer a reason for me to have the Windows 10 Mobile emulators installed, which means I have no need for Hyper-V, which means I can use any one of the great Android emulators out there that don’t play nice wiht Hyper-V.

What’s really cool is that Microsoft have included the Google Android Emulator in the Visual Studio installer. You need to make sure that both the Google Android Emulator and the Intel Hardware Accelerated Execution Manager are installed.

image

After installing the Google emulator you can launch your application on the emulator the same way you would to a real device – it appears in the devices dropdown. You can also access the different emulator images via the Android Emulator Manager.

image

Whilst the Android Emulator Manager is not a great looking dialog, it does allow you to customise and launch the different emulators.

image

I was so surprised when I launched the updated emulator. I was expecting an old, slow, crappy looking emulator but was surprised with an updated emulator shell with all the features that I’d come to expect from an emulator.

image

I’m a convert – Whilst I’ll still use a real device for most development work, having a good emulator is critical for those times when I don’t have a device with me. Cudos to Microsoft for firstly pushing Google to build a better developer experience and secondly making the Visual Studio installer so simple to install the emulator.

Sidenote: I did have to update one component from the Android SDK. Make sure you read the build output window in Visual Studio if you are running into issues as it pointed me to an out of date component.

Visual Studio or Blend Exception When Using XAML Designer

Today we ran into a nasty issue with the XAML design experience in Visual Studio and/or Blend throwing an exception:

image

Exceptions in the designer a quite often a result of code being run by the designer that is insufficiently protected using try-catch, or has assumptions that some app startup code has run, resulting in an exception that bubbles up and causes the designer to fail. For these exceptions, I recommend checking out the post How to Debug the XAML Designer by Travis Illig, which uses another instance of Visual Studio to debug and hopefully identify the code that isn’t playing nice.

Unfortunately in our case, this didn’t help because Visual Studio (and same in Blend) was failing to resolve an assembly reference.

image

One thing that Travis point out is that there is a ShadowCache folder located at C:\Users\yourusername\AppData\Local\Microsoft\VisualStudio\15.0_317bf9c1\Designer\ShadowCache (note that you’ll need to change both “yourusername” to be your username and perhaps even the 15.0…. to reflect the current version of Visual Studio. Change VisualStudio to Blend if you’re using Blend). Within the ShadowCache folder there will be folders created for each application where you use the designer, and then a series of “bin” sub folders that will contain assemblies referenced by your application.

image

The issue we found was that we were referencing a nuget package that includes both a UWP dll as well as a .NET Standard dll. Whilst the UWP dll was being copied into a bin folder, the .NET Standard dll was not. Our fix for getting the designer to work was to copy the .NET standard dll into the same folder as the UWP dll.

Unfortunately whilst this gets the designer to work, it is a sub-optimal experience as it appears that it needs to be done every time Visual Studio is run, or when the designer process is restarted.

Getting Started: Xamarin Forms with .NET Standard 2.0

In my earlier post Getting Started: Xamarin Forms with .NET Standard I covered how to create a new Xamarin Forms project which uses a .NET Standard 1.4 library to share the views between iOS, Android and UWP. At the time, whilst iOS and Android supported .NET Standard 2.0, support still wasn’t available for UWP. Almost immediately after publishing the blog post, Microsoft announced that Visual Studio 2017 preview 15.4 would allow UWP applications to reference .NET Standard 2.0 libraries. Unfortunately this didn’t work in the first drop, 15.4.0 Preview. This was just updated to 15.4.0 Preview 2 (Release Notes: https://www.visualstudio.com/en-us/news/releasenotes/vs2017-preview-relnotes), which brings with it the support we’ve been after. In this post, I’m going to repeat the previous post on getting started with .NET Standard, this time using .NET Standard 2.0 for the UI project.

Let’s walk through the basics – create a new Cross Platform App (same as before)

image

Select the Xamarin.Forms (UI Technology) and Portable Class Library (PCL) (Code Sharing Strategy) – Don’t pick the Shared Project option!

image

Select the Insider Preview version of UWP for both Minimum and Target version – this is required for .NET Standard 2.0 support. If you want to target earlier versions of Windows 10, you’ll have to stick with .NET Standard 1.4.

image

Next, we’re going to replace the PCL with a new .NET Standard library

image

I’ll copy the App.xaml, App.xaml.cs, MainPage.xaml and MainPage.xaml.cs from the PCL into the .NET Standard library, before deleting the PCL from the project (see https://nicksnettravels.builttoroam.com/post/2017/08/26/Getting-Started-Xamarin-Forms-with-NET-Standard.aspx for more detailed instructions).

The big difference is that I’m not going to change the default Target Framework, leaving it as .NET Standard 2.0.

image

Next I need to make sure I add and upgrade references to Xamarin.Forms to each of the projects �� this isn’t actually required, since the stable release of Xamarin Forms will actually work with .NET Standard but I’ve been working with the pre-release version quite a bit lately, so I’ll go with that for this example.

image

I also need to remember to add a reference to the .NET Standard project to each of the head projects for iOS, Android and UWP.

image

If you attempt to build and run at this point iOS and Android should work without issue. UWP will most likely compile but will raise an exception “Could not load file or assembly ‘netstandard, Version=2.0.0.0….” at runtime.

image

Essentially the UWP project structure has evolved a little, so you need to upgrade it. Now I think that you may be able to do this via package manager but I’ve never got it to work for UWP projects, so I will make the changes manually to the csproj file. Start by deleting the project.json file from the UWP project.

Next right-click the UWP project in Solution Explorer and select unload project. Next, right-click on the UWP project node and select Edit MySecondXamarinFormsApp.UWP.csproj.

Add a new PropertyGroup – this changes the way packages are referenced, eliminating the need for the project.json file, replacing it with references within the csproj file.

<PropertyGroup>
   <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>

image

Next we need to add back the package references that were in the project.json – if you’re doing this on an existing project, you may want to keep the project.json file handy so you know which packages to add. In this case there are just two projects:

<ItemGroup>
   <PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
     <Version>6.0.0-preview1-25631-01</Version>
   </PackageReference>
   <PackageReference Include="Xamarin.Forms">
     <Version>2.4.0.269-pre2</Version>
   </PackageReference>
</ItemGroup>

image

Now you can right-click on the UWP project in Solution Explorer and select Reload project. Trigger a rebuild and now you should be able to run the UWP project.

image

Source Code Debugging with BuildIt Libraries

I was working on the BuildIt libraries yesterday and got slightly distracted – I was looking for how to make a small change to the way the Nuget packages are generated and ended up investing time in getting symbol source server support added. At first I thought “this is going to be easy and so awesome” but this quickly turned into frustration as it just didn’t seem to work. Turns out that whilst I was able to successfully generate the nuget symbol package locally, what I’d forgotten is that because we separate our build and release process (done via Visual Studio Team Services), I needed to make sure all my source code files are added to the build artefacts. The nuget packages are generated as part of our release process, which includes generating the symbol package which needed to include the source code files.

The upshot is that I’ve got source code debugging added to both BuildIt.General and BuildIt.States, with other packages to get it as we roll out stable builds in the coming weeks.

To get source code debugging to work, the first step is to configure Visual Studio to use the symbolsource server when attempting to step through source code. I followed the instructions at http://www.symbolsource.org/Public/Home/VisualStudio, which I’ve repeated here with the exact setup I used:

In Visual Studio:

  • Go to Tools -> Options -> Debugger -> General.
    • Uncheck “Enable Just My Code (Managed only)”.
    • Uncheck “Enable .NET Framework source stepping”.
    • Check “Enable source server support”.
    • Uncheck “Require source files to exactly match the original version”

image

image


With this all setup, you’ll find that the next time you run your application it will be incredibly slow to start debugging as it has to go through and look up the symbols for each library you have references. However, when you do finally get your application up and running you’ll be able to step through and see more information about what’s going wrong with third party libraries that have symbol and source code support.

For the BuildIt libraries (General and States) the only additional step is to update to the latest stable release (1.1.0.75 at time of writing). Run the application, and you can now step through on calls made to functions contained within these libraries. You’ll also be able to intercept any exceptions that are raised within the libraries.

image

Happy Debugging!

Getting Started: Xamarin Forms with .NET Standard

With the recent release of Visual Studio 2017 v15.3 (and subsequent patch release 15.3.1 and 15.3.2…. yes, it does say something about ship quality Sad smile) came the release and support for .NET Standard 2.0. The Xamarin team also made a lot of noise about support for .NET Standard 2.0; unfortunately this doesn’t yet translate into Visual Studio templates that easily get you started. My particular annoyance is the about of steps you need to go through in order to just spin up a new Xamarin Forms application that can reference .NET Standard libraries. I thought I’d piggyback of a post done a couple of months back by Pierce Boggan. Here goes:

Start by creating a new project in Visual Studio 2017, selecting the Cross Platform App (Xamarin) project template:

image

Next, select the template you want (I’m going with the Blank App), the UI Technology and Code Sharing Strategy. As I’m going to be walking through how to use Xamarin Forms, it makes sense to pick that as the option for UI Technology. Only select the Portable Class Library option. Don’t use the Shared Project – using a shared project will lead you down the evil road of using conditional compilation which will be a maintenance nightmare, just don’t use it. I don’t care how great you think it is, don’t use it. One last time, don’t use the Shared Project option.

image

Now that I’ve expressed my opinion on code sharing strategies, let’s click the OK button and get on with building our application. As the template goes through generating the head projects for iOS, Android and UWP, it will prompt you to select the target and minimum platforms for UWP. For the most part, unless you have specific target platform requirements for UWP, you can leave the default settings.

image

The generated solution will have four projects: three head or target platform projects (for iOS, Android and UWP) and a portable class library (PCL) which contains the XAML pages that will make up your Xamarin Forms application layout. In order to proceed with .NET Standard support we need to replace the PCL with a .NET Standard library. Whilst Visual Studio used to have a mechanism for upgrading a library from a PCL to a .NET Standard library, this has been removed. Now the easiest way is to simply create a new project, and copy the relevant files into the new project. From the Add New Project dialog, select the Class Library (.NET Standard) template.

image

I use the .UI naming convention for the library that will contain my XAML pages. Other developers use .Core but my preference is to separate my XAML pages away from my view models. Whilst technically with Xamarin Forms they can reside in the same library, I prefer to have a clean separation between them. I have <applicationname>.UI with my XAML pages in it and <applicationname>.Core with my view models, services, entities, essentially all the business logic for my application.

For this example I’m going to keep it simple and we’ll just create the .UI project for the moment.

image

I don’t need the default Class1.cs, so I’ll remove that. I’ll add a reference to the .NET Standard library to all the head projects.

I’m also going to drop the .NET Standard version back from 2.0 (now the default in Visual Studio) back to 1.4. Whilst the tooling has been updated for the head projects for iOS and Android to support .NET Standard 2.0, of course, UWP is still lagging the field, as so you won’t be able to use a .NET Standard 2.0 library until that’s fixed. To be honest though, not much is lost by lowering the version of the .UI project to 1.4 since all the features of Xamarin Forms are still there.

image

Next I’m going to copy App.xaml (and App.xaml.cs) and MainPage.xaml (and MainPage.xaml.cs) from the PCL into the newly created .NET Standard library. Once I’ve copied these files across I can remove the PCL project from the solution – this will remove the references to this library from each of the head projects. After coping these files across, you may well see a compilation error similar to the following:

1>------ Build started: Project: MyFirstXamarinFormsApp.UI, Configuration: Debug Any CPU ------
1>C:\Program Files\dotnet\sdk\2.0.0\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.DefaultItems.targets(274,5): error : Duplicate 'EmbeddedResource' items were included. The .NET SDK includes 'EmbeddedResource' items from your project directory by default. You can either remove these items from your project file, or set the 'EnableDefaultEmbeddedResourceItems' property to 'false' if you want to explicitly include them in your project file. For more information, see
https://aka.ms/sdkimplicititems. The duplicate items were: 'App.xaml'; 'MainPage.xaml'
1>Done building project "MyFirstXamarinFormsApp.UI.csproj" -- FAILED.

If you do, you just need to edit the project file for the .UI project and remove the App.Xaml and MainPage.xaml EmbeddedResource elements. The new project format includes files by default and the tooling isn’t smart enough to realise that the sample files are being added multiple times. Removing these elements will fix the compilation:

<ItemGroup>
   <EmbeddedResource Include="App.xaml">
     <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
   </EmbeddedResource>
   <EmbeddedResource Include="MainPage.xaml">
     <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
   </EmbeddedResource>
</ItemGroup>

The last thing to do is to make sure that the .NET Standard library references Xamarin Forms. I’m going to do that by right-clicking the solution node in Solution Explorer and selecting Manage Nuget Package for Solution.

image

I’m going to select the new prerelease version of Xamarin Forms (which is the one where they’ve apparently added .NET Standard support). In addition to adding a reference to Xamarin Forms to the UI project, I also take this opportunity to upgrade all the package references in the application. Note that I’ve even selected the Android support packages – this used to be a big No-No but with the latest version of the tooling you can now go ahead and update them, and I would definitely encourage you to do so.

image

Now, go make yourself a coffee – Nuget is slow, so slow! The good news is that once you’ve done all these steps, you’re ready to go with a .NET Standard based Xamarin Forms project. If you’re following this post to get started on your own project, you can finish up here, as you’re good to go.

Ok, so all of that, and what can we do. We’ll for a starters, it makes it super easy to add nuget packages such as BuildIt Forms which has a bunch of helper controls and features to get you building richer applications. Let’s add a reference to the BuildIt.Forms Nuget package the project:

image

After adding the reference to BuildIt.Forms we can make use the added controls. For example the ContentButton allows us to easily add a button that contains any XAML content, whilst still maintaining the pressed and hover states:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="
http://xamarin.com/schemas/2014/forms"
              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
              xmlns:local="clr-namespace:MyFirstXamarinFormsApp"
              xmlns:ctrls="clr-namespace:BuildIt.Forms.Controls;assembly=BuildIt.Forms.Controls"
              x:Class="MyFirstXamarinFormsApp.MainPage">
 
     <StackLayout VerticalOptions="Center"
                  HorizontalOptions="Center">
         <Label Text="Welcome to Xamarin Forms!" />
         <ctrls:ContentButton>
             <Label Text="Press m!" />
         </ctrls:ContentButton>
     </StackLayout>
</ContentPage>

I’ll cover more on the BuildIt.Forms library in coming posts.

Visual State Transitions in Xamarin Forms with Animations

In previous posts (Visual States in Xamarin.Forms using BuildIt.Forms and Xamarin.Forms Visual States with View Models) I demonstrated how the BuildIt.Forms library (https://www.nuget.org/packages/BuildIt.Forms) could be used to declare visual states for pages, and controls, within Xamarin Forms. Today we just added some basic support for animations so that as you transition between visual states you can animate elements of the screen:

The following visual states define animations for rotating a green square:

<Grid HeightRequest="100" WidthRequest="100" x:Name="AnimateGrid" HorizontalOptions="Start" BackgroundColor="Green" />

The Hide visual state defines three animations that run in parallel, with the rotation being a sequence of animations. The Show visual state has the reverse animations to return the green square to the original starting position. Unlike the setters, there’s no built in support for returning the element to its unchanged state.

<vsm:VisualStateManager.VisualStateGroups>
     <x:Array Type="{x:Type vsm:VisualStateGroup}">
         <vsm:VisualStateGroup Name="SampleStates">
             <vsm:VisualState Name="Show">
                 <vsm:VisualState.Animations>
                     <vsm:TranslateAnimation TranslationX="0" Duration="500" Target="AnimateGrid"/>
                     <vsm:FadeAnimation Opacity="1" Duration="500" Target="AnimateGrid"/>
                     <vsm:RotateAnimation Rotation="0" Duration="500" Target="AnimateGrid"/>
                 </vsm:VisualState.Animations>
             </vsm:VisualState>
             <vsm:VisualState Name="Hide">
                 <vsm:VisualState.Setters>
                     <vsm:Setter Value="false"
                                 Target="WelcomeText.IsVisible" />
                 </vsm:VisualState.Setters>
                 <vsm:VisualState.Animations>
                     <vsm:ParallelAnimation>
                         <vsm:TranslateAnimation TranslationX="200" Duration="3000" Target="AnimateGrid"/>
                         <vsm:FadeAnimation Opacity="0.2" Duration="3000" Target="AnimateGrid"/>
                         <vsm:SequenceAnimation>
                             <vsm:RotateAnimation Rotation="135" Duration="750" Target="AnimateGrid"/>
                             <vsm:RotateAnimation Rotation="0" Duration="750" Target="AnimateGrid"/>
                             <vsm:RotateAnimation Rotation="135" Duration="750" Target="AnimateGrid"/>
                             <vsm:RotateAnimation Rotation="0" Duration="750" Target="AnimateGrid"/>
                         </vsm:SequenceAnimation>
                     </vsm:ParallelAnimation>
                 </vsm:VisualState.Animations>
             </vsm:VisualState>
         </vsm:VisualStateGroup>
     </x:Array>
</vsm:VisualStateManager.VisualStateGroups>

This is how these animations play out:

animations

Adding Fluent Design Acrylic Material to UWP via Xamarin.Forms.

At Build Microsoft made a big deal out of the new Fluent Design that they’re encouraging developers to start taking advantage of. Out of the box it’s a little harder to take advantage of these features but using BuildIt.Forms it’s easy to start using acrylic material resources. Let’s extend the example I’ve covered in the last couple of posts (Visual States in Xamarin.Forms using BuildIt.Forms and Xamarin.Forms Visual States with View Models). I’ve added a Grid, that will span the whole page (the StackLayout was positioned to keep all the elements in the centre of the page) and included the BackgroundEffect to set the background of the whole page.

<Grid>
     <Grid.Effects>
         <ctrls:BackgroundEffect Resource="SystemControlAcrylicWindowBrush" />
     </Grid.Effects>

     <StackLayout VerticalOptions="Center"
                     HorizontalOptions="Center">

        <Label x:Name="WelcomeText"
                 Text="{Binding WelcomeText}" />
         <StackLayout Orientation="Horizontal">
             <Button Text="Show"
                     Clicked="ShowClicked" />
             <Button Text="Hide"
                     Clicked="HideClicked" />
         </StackLayout>
     </StackLayout>
</Grid>

The Resource attribute defines the UWP brush resource that will be used as the background. In this case the SystemControlAcrylicWindowBrush is one of the build in arcylic brushes. As you can see the page appears as translucent, allowing what’s behind the app to taint the background of the app.

image

It’s also possible to use a custom acrylic resource, defined in the App.xaml of the UWP application

<Application
     x:Class="FormsWithStates.UWP.App"
     xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:local="using:FormsWithStates.UWP"
     RequestedTheme="Light">
     <Application.Resources>
         <ResourceDictionary>
             <ResourceDictionary.ThemeDictionaries>
                 <ResourceDictionary x:Key="Default">
                    <AcrylicBrush x:Key="MyAcrylicBrush"
                                   BackgroundSource="HostBackdrop"
                                   TintColor="#FFFF0000"
                                   TintOpacity="0.4"
                                   FallbackColor="#FF7F0000" />

                 </ResourceDictionary>

                <ResourceDictionary x:Key="HighContrast">
                     <SolidColorBrush x:Key="MyAcrylicBrush"
                                      Color="{ThemeResource SystemColorWindowColor}" />

                 </ResourceDictionary>

                <ResourceDictionary x:Key="Light">
                     <AcrylicBrush x:Key="MyAcrylicBrush"
                                   BackgroundSource="HostBackdrop"
                                   TintColor="#FFFF0000"
                                   TintOpacity="0.4"
                                   FallbackColor="#FFFF7F7F" />

                 </ResourceDictionary>
             </ResourceDictionary.ThemeDictionaries>
         </ResourceDictionary>
     </Application.Resources>
</Application>

image

The BackgroundEffect also supports a FallbackColor attribute which can be used to set the background colour on all platforms.

Xamarin.Forms Visual States with View Models

In my previous post, Visual States in Xamarin.Forms using BuildIt.Forms, I showed how to use BuildIt.Forms (https://www.nuget.org/packages/BuildIt.Forms) to create visual states that can be used to define how the user interface changes to reflect different states of the page. The example demonstrated switching between visual states in the code behind with calls to VisualStateManager.GoToState. In this post I’m going to extend the example to allow the states to be switched from a view model.

I’ll start by creating a view model that will be data bound to the page. Usually I’d use a framework like MvvmCross to drive the view model/view instantiation but for this example I’ll keep it simple. I will however still put the view model in a separate project – again this promotes good separation between the view models and their associated view. I’ll create a new .NET Standard library, FormsWithStates.Core, and add a reference to it into the FormsWithStates.UI project.

image

I’ll add a new class to the project, MainViewModel, which will be the view model for the MainPage of the application. To track states within the view model, I need to add a reference to the BuildIt.States library on NuGet.

image

The MainViewModel will define a simple property WelcomeText to demonstrate that the view model is indeed data bound to the page. It also implements the interface IHasStates which defines a property StateManager – you can think of the IStateManager implementation as an object that can track states and state transitions.

public enum SampleStates
{
     Base,
     Show,
     Hide
}

public class MainViewModel : IHasStates
{
     public IStateManager StateManager { get; } = new StateManager();

    public string WelcomeText => "Welcome to Forms!";

    public MainViewModel()
     {
         StateManager.Group<SampleStates>().DefineAllStates();
     }

    public void Show()
     {
         StateManager.GoToState(SampleStates.Show);
     }
     public void Hide()
     {
         StateManager.GoToState(SampleStates.Hide);
     }
}

The enumeration SampleStates defines the states that the MainViewModel references – both the enumeration and the states themselves have to match the names of the visual state group and visual states defined in the XAML for the page. The final step is to link the visual states on the page to the IStateManager instance, so that when there is a state change in the IStateManager, it will be reflected on the page via a change to the visual states. This is done by the Bind method on the VisualStateManager class.

public partial class MainPage : ContentPage
{
     private MainViewModel ViewModel { get; } = new MainViewModel();
     public MainPage()
     {
         InitializeComponent();

        BindingContext = ViewModel;
         VisualStateManager.Bind(this, ViewModel.StateManager);
     }

    public void ShowClicked(object sender, EventArgs e)
     {
         ViewModel.Show();
     }
     public void HideClicked(object sender, EventArgs e)
     {
         ViewModel.Hide();
     }
}

Whilst from the perspective of a user, there is no difference (since the Show and Hide buttons do the same thing), state management has been shifted to the view model where it can be tested. This separation of views and view models is important to ensure all application logic can be tested.

Visual States in Xamarin.Forms using BuildIt.Forms

A couple of weeks ago I started building out some helpers to make working with Xamarin.Forms a little nicer (see Styling Pages and Controls in Xamarin Forms using Visual States,Rebuilding the Xamarin.Forms Button with Visual States and Control Templates and Ambient Properties in Xamarin.Forms). Since then we’ve been working on building out a library that encapsulates these features, again making it easier for us and others to build apps using Xamarin.Forms. There is now a pre-release version of BuildIt.Forms (https://www.nuget.org/packages/BuildIt.Forms) that anyone can reference to take advantage of these helpers. The library makes use of some methods/properties that are only available in the pre-release version of Xamarin.Forms, which is why we don’t have an actual release out yet.

In this post I’m going to walk through using visual states in a Xamarin.Forms project. To set the scene, I’m going to step through creating a new Xamarin.Forms project in Visual Studio 2017 (current RTM build, not the preview, although the preview build should be similar). I’ll do this in this post to make sure the basics of creating a Xamarin.Forms project that uses a .NET Standard Library instead of a PCL library is covered. I highly recommend switching to a .NET Standard library as soon as possible to avoid issues with upgrading nuget references etc (most third party library now have a .NET Standard version and it will become increasingly harder to maintain and update your old PCL libraries).

Ok, so let’s get started with a new project – I’m going with the Cross Platform App (Xamarin) template in the New Projects dialog:

image

Next, I’ll select the Blank App template, using Xamarin.Forms (UI Technology) and Portable Class Library (Code Sharing Strategy). Side note here – I highly recommend not using the Shared Project option for Code Sharing Strategy; using this option is a recipe for disaster as it promote poorly separated UI logic and allows for using conditional compilation based on #defines which is not a good strategy if you want maintainable code.

image

After clicking OK my solution has four projects: A PCL which has got the Xamarin.Forms UI defined in XAML files, and three “head” projects, one for each target platform. At this point, I would suggest running each project to make sure you have a working application before going any further (and commit this code to your source repository before going any further!)

image

Now to replace the PCL with a .NET Standard library. I’ll add a new .NET Standard class library. I like to make it clear that this library will contain the UI for my Xamarin.Forms project by using the .UI suffix. I do not include my view models in this library – I’ll talk about this in a subsequent post.

image

After creating the new class library, I just need to copy across the XAML and .cs files that were in the PCL library (App.xaml, App.xaml.cs, MainPage.xaml, MainPage.xaml.cs).  I can then remove the PCL library from the solution. Of course, I need to go through each of the head projects and add a reference to the UI project.

image

At this point I would again build and run the application on each platform – If you do this without doing anything the solution won’t compile as the UI library doesn’t have a reference to the Xamarin.Forms NuGet library. I suggest adding a reference to the Xamarin.Forms NuGet library and then upgrading any libraries where there is an update available. Again before proceeding, build and run each platform.

The next step is to add a reference to BuildIt.Forms. This is a prerelease library so you’ll need to check the “Include prerelease” option when searching. You need to add this library to all projects, even though you’ll only be adding code into the UI project – this makes sure the platform specific libraries that are included in BuildIt.Forms are correctly referenced and will be included.

image

As part of referencing BuildIt.Forms you will notice that the reference to Xamarin.Forms has also been updated to the prerelease version – as BuildIt.Forms takes advantage of some prerelease APIs this is unavoidable at the moment. The official release of BuildIt.Forms will not be available until the next drop of Xamarin.Forms where these APIs come out of prerelease.

Now we can start to make use of some of the helpers in BuildIt.Forms. In this case we’re going to use visual states in the XAML for the MainPage to hide and show a Label. The following XAML includes a Label and two Button elements. There are two visual states defined: Show and Hide (the actual names are only relevant when switching visual states, they have no bearing on what the visual states do). Note that the Show visual state doesn’t need to explicitly set the IsVisible property on the WelcomeText Label to true, since this is the default value for that property.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="
http://xamarin.com/schemas/2014/forms"
              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
              xmlns:vsm="clr-namespace:BuildIt.Forms.Core;assembly=BuildIt.Forms.Core"
              xmlns:local="clr-namespace:FormsWithStates"
              x:Class="FormsWithStates.MainPage">
     <vsm:VisualStateManager.VisualStateGroups>
         <x:Array Type="{x:Type vsm:VisualStateGroup}">
             <vsm:VisualStateGroup Name="SampleStates">
                <vsm:VisualState Name="Show" />
                 <vsm:VisualState Name="Hide">
                     <vsm:VisualState.Setters>
                         <vsm:Setter Value="false"
                                     Target="WelcomeText.IsVisible" />
                     </vsm:VisualState.Setters>
                 </vsm:VisualState>

             </vsm:VisualStateGroup>
         </x:Array>
     </vsm:VisualStateManager.VisualStateGroups>
     <StackLayout VerticalOptions="Center"
                  HorizontalOptions="Center">
         <Label x:Name="WelcomeText"
                Text="Welcome to Xamarin Forms!" />
         <StackLayout Orientation="Horizontal">
             <Button Text="Show"
                     Clicked="ShowClicked" />
             <Button Text="Hide"
                     Clicked="HideClicked" />
         </StackLayout>
     </StackLayout>
</ContentPage>

The code for the event handlers for the two button is relatively simple:

public void ShowClicked(object sender, EventArgs e)
{
     VisualStateManager.GoToState(this, "Show");
}
public void HideClicked(object sender, EventArgs e)
{
     VisualStateManager.GoToState(this, "Hide");

}

And the final result is an interface that shows and hides the welcome text on the page:

imageimage

Feel free to try out the BuildIt.Forms library and get started using visual states within your Xamarin.Forms project.

Ambient Properties in Xamarin.Forms

One of the aspects of XAML that is often misunderstood is that of ambient properties. Probably the best example of this is being able to set the foreground colour on a Page in UWP and for the foreground color to be set on every element on the page. Unfortunately this doesn’t seem to be something that’s available in Xamarin.Forms, which lead me to wonder how hard it would be to implement.

The implementation would be slightly different from UWP which uses the AmbientAttribute. Instead I’ll create an attached property which can be set on any element. The ForeColor will be then set on each child element, unless the TextColor is explcitly set on an element.

For example the following XAML

<StackLayout
    vsm:Ambient.ForeColor="Blue">
     <Label Text="Hello World - Blue!" />
     <Label TextColor="Red"
             Text="Hello World - Red!" />
</StackLayout>

would generate the following output

image

Over the next couple of days the Ambient.ForeColor property will be added to BuildIt.Forms, which also includes the VisualStateManager I described in my past two posts (here and here).

Rebuilding the Xamarin.Forms Button with Visual States and Control Templates

In my previous post I provided a demonstrable way that visual states could be used in a Xamarin.Forms application to adjust layout. Whilst I showed how this can be used on a page to show/hide a piece of text, it can also be used to define the different states of a button. Before I get onto using visual states within a button, I’ll first show how a ContentView can be adapted to provide the basic button behaviour, whilst allowing both Content and ControlTemplate to be defined. Ok, perhaps that doesn’t make sense but let’s walk through an example:

<controls:ContentButton Pressed="ToggleButtonPressed">
    <StackLayout>
        <Label Text="Hello!" />
        <Label Text="Hello!" />
        <Label Text="Hello!" />
        <Label Text="Hello!" />
        <Label Text="Hello!" />
        <Label Text="Hello!" />
    </StackLayout>
</controls:ContentButton>

In this code, I can add any XAML elements as Content within the ContentButton tags. The ContentButton raises a Pressed event, instead of a Click or Clicked event, to which an event handler can be attached. In the next code snippet, I’ve overridden the default ControlTemplate, wrapping the ContentPresenter in a Grid which has a yellow background.

<controls:ContentButton VerticalOptions="Center"
                        x:Name="DisabledButton"
                        HorizontalOptions="Center">
    <ContentView.ControlTemplate>
        <ControlTemplate>
            <Grid BackgroundColor="Yellow">
                <ContentPresenter x:Name="ContentPresenter"
                                    Content="{TemplateBinding Content}" />
            </Grid>
        </ControlTemplate>
    </ContentView.ControlTemplate>
    <StackLayout>
        <Label Text="Hello!" />
        <Label Text="Hello!" />
        <Label Text="Hello!" />
        <Label Text="Hello!" />
        <Label Text="Hello!" />
        <Label Text="Hello!" />
    </StackLayout>
</controls:ContentButton>

Overriding the ControlTemplate demonstrates an easy way to override the style of the button in a way that can be replicated across all instances of the button in an application.

Let’s take a look at the inner workings of the ContentButton, in particular the default ContentTemplate which is used to define different visual states of the button. In this case there are four visual states: Normal, PointerOver, Pressed and Disabled.

<ContentView.ControlTemplate>
    <ControlTemplate>
        <Grid x:Name="RootGrid" BackgroundColor="{TemplateBinding BackgroundColor}">
            <local:VisualStateManager.VisualStateGroups>
                <x:Array Type="{x:Type local:VisualStateGroup}">
                    <local:VisualStateGroup Name="CommonStates">
                        <local:VisualState Name="Normal" />
                        <local:VisualState Name="PointerOver">
                            <local:VisualState.Setters>
                                <local:Setter Value="#33000000" Target="Background.BackgroundColor" />
                            </local:VisualState.Setters>
                        </local:VisualState>
                        <local:VisualState Name="Pressed">
                            <local:VisualState.Setters>
                                <local:Setter Value="#66000000" Target="RootGrid.BackgroundColor" />
                            </local:VisualState.Setters>
                        </local:VisualState>
                        <local:VisualState Name="Disabled">
                            <local:VisualState.Setters>
                                <local:Setter Value="#33000000" Target="Background.BackgroundColor" />
                            </local:VisualState.Setters>
                        </local:VisualState>
                    </local:VisualStateGroup>
                </x:Array>
            </local:VisualStateManager.VisualStateGroups>
           
<BoxView BackgroundColor="Transparent" x:Name="Background" />
            <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Content}" />
        </Grid>
    </ControlTemplate>
</ContentView.ControlTemplate>

In this code you can see how the visual states (which I introduced in my previous post) are used to adjust the background colour of the BoxView that sits behind the Content of the button.

The sample project that demonstrates the ContentButton can be downloaded here

Styling Pages and Controls in Xamarin Forms using Visual States

I’ve been a bit proponent of both Xamarin and Xamarin.Forms for a long time but recently I’ve been taking another look at some of the fundamentals. Xamarin.Forms, for all its great intent is still a poor-man’s answer to declaring layout of an application in Xaml. Unlike Xaml platforms that have come before it (WPF, Silverlight, UWP), Forms doesn’t support some of even the basic features that you’d expect. On the chopping board today is the Button control – as one of the fundamental controls for any application, the Button should be able to be completely customised. Unfortunately it’s far from easy to alter the look of the basic button.

If you look at how a simple button renders on different platforms, there is a clear difference between the style of the button. The following image shows how the button control renders across UWP, iOS and Android (UWP has an extra visual state as it supports mouse/pointer over on desktop).

image

Button States Across Three Platforms

The difference in style is by design – the rendering of the button on each platform uses the built in style for each platform. This works well if you’re interesting in building a generic looking application (eg perhaps a simple LOB data capture application). However, if you want to style the button in line with your branding and the design of your application, you’re going to want to make the buttons look and behave the same across all devices. You’d think this would be as simple as defining a common style, or perhaps overriding the default layout of the button. This is in fact doable – for example on UWP you can use an implicit style to override the look of every button across the application.

Having to override the style of the button on each platform defeats the purpose of using Forms in the first place – once you’ve overridden the style, you then need to make platform specific changes every time you want to alter the style of the button control; imagine doing this for every control in your application – pretty soon, you might as well have developed the application using the traditional Xamarin model, rather than Forms. So, let’s look at the limitations of the Button control and see what we can do to address some of its shortcomings in a way that will help us build better applications quicker.

There are two issues that I have with the Button control. The first is that it’s not easy to customise the content within the Button itself. For example if you wanted to have two lines of text, with the first being centred in bold, and the second justified italics with word wrapping enabled to allow it to flow to multiple lines. In UWP this would be easy with the Button control as the Content could be customised to have multiple TextBlock elements, with the style set accordingly.

<Button>
    <StackPanel>
        <TextBlock Text="Hello World!"
                    TextAlignment="Center"
                    FontWeight="Bold" />
        <TextBlock Text="This is a short message that should word wrap with all the lines being set to justified"
                    FontStyle="Italic"
                    TextWrapping="WrapWholeWords"
                    TextAlignment="Justify" />
    </StackPanel>
</Button>

This would look similar to the following:

image

UWP Button with Custom Content

Attempting to do this with the Forms Button control is not trivial. The second issue is how the different visual states are handled. Again in UWP the different Button visual states are defined in XAML (generic.xaml) where appropriate properties are set based on the active states (eg Normal, Pressed, PointerOver). Forms doesn’t support Visual States, so attempting to define Button states declaratively is going to take more work.

My solution to these issues comes in two steps: firstly, provide a declarative way to define Visual States in XAML, similar to what’s available in UWP; and secondly to provide an alternative to the Button which can not only take custom content but also has a template that can be override to customise behaviour for different button states. If you’ve ever drilled into a control template for a UWP control, chances are that it has some visual states defined. Rather than having some predefined behaviour that’s not accessible or customisable, the various states of UWP controls are defined in XAML in the template for the control. In addition to defining the different states within a control, visual states can be used to define different states of a page too.

In this post we’ll focus on the first step, which is how to define in XAML and then apply visual states. Visual states are defined in visual state groups, and only a single state within a given states group can be active at any time (ie they’re mutually exclusive). However, it is possible that two states, from different groups can be active at any point in time.

So far we know we need visual states, defined within visual state groups. Within each visual state we need to be able to define which properties are going to change when the visual state is made active. UWP allows the property changes to be defined either as a storyboard, potentially with animation, or as a series of setters where the property is updated to the new value immediately. For the purposes of getting the basics working, we’re just going to work with property setters.

Let’s work with a very simple scenario where we have a simple Label which we need to be able to show and hide based on the state of the page:

<Label FontSize="30"
        x:Name="HelloLabel"
        Text="Hello World!" />

In our very contrived example we have a button that will be used to toggle whether the Label is visible.

private bool visible = true;
public void ToggleButtonPressed(object sender, EventArgs e)
{
    visible = !visible;
    VisualStateManager.GoToState(this, visible ? "Show":"Hide");
}

This code, by design, is similar to what you might see within a UWP application that uses visual states to control the layout – in this case showing and hiding an element. Currently visual states don’t exist in Xamarin Forms but here’s a first pass on an implementation of visual states:

<vsm:VisualStateManager.VisualStateGroups>
    <x:Array Type="{x:Type vsm:VisualStateGroup}">
        <vsm:VisualStateGroup Name="LabelStates">
            <vsm:VisualState Name="Show" />
            <vsm:VisualState Name="Hide">
                <vsm:VisualState.Setters>
                    <vsm:Setter Value="false"
                                Target="HelloLabel.IsVisible" />
                </vsm:VisualState.Setters>
            </vsm:VisualState>
        </vsm:VisualStateGroup>
    </x:Array>
</vsm:VisualStateManager.VisualStateGroups>

For those familiar with the syntax in UWP this should look familiar – there’s a few kinks to work out (for example the use of the Array tag) but in its initial form it works.

Sample project can be downloaded here

Thinking about Synchronisation in a Cloud-First World

As a mobile applications enthusiast from way back before Windows Mobile was a thing (yeh, I mean the first time), one of the challenges has always been data synchronisation. The challenge comes down to a trade off between stale data and user experience. Simple applications don’t worry about any form of data synchronisation; instead relying on pulling whatever data they need, when they need it. Unfortunately, these applications feel like the user is always waiting on data, or worse, seeing no data or error messages when there’s no connection. In order to fix, what is essentially a user experience issue, application developers often look at caching, or synchronising, data so that it can be made available offline. This both improves performance, since data is read from what’s cached on the device, it also means the data can be access when offline. The inevitable question is then how much data should be cached, and how should data be synchronised.

There is no golden-bullet when it comes to identifying what data needs to be cached on the device. Some applications only cache data that the user has chosen to look at; allowing them to come back and review the data at a later point without having to request the data again. Other applications will proactively cache all data related to the current user – whilst this seems like a good idea initially, as the data related to a user increases, so does the time taken to complete an initial, or even future, synchronisations. In addition, the logic to retrieve all data related to a user can grow in complexity, often resulting in more data than necessary being retrieved, to ensure no data is omitted.

Data synchronisation used to be an important topic with several attempts being made by Microsoft to assist developers. For example there was a Windows Mobile client for Merge Replication; there was the Microsoft Sync Framework and more recently the Mobile App Service has a limited form of data synchronization. Unfortunately none of these methods are well supported. Nor are they optimised to take advantage of some the benefits of the cloud.

Let’s look at the most recent attempt by Microsoft to provide a synchronisation framework for mobile apps – Offline Data Sync for Azure Mobile Apps. The basic premise is that the application defines a table, or a query on a table, that will be pulled into a local Sqlite database. Local changes can be made to the data. Data can then be synchronised by pulling any server side changes and pushing local changes to the server. The architecture has the mobile application connecting to a service, which then either retrieves data from the database, or submits changes to the database.

Thinking about how a cloud application should scale, there are a number of issues with this architecture:

  • If you look at how to scale cloud applications, having any services which connect directly to the database, can be a source for bottlenecks. I’m definitely not advocating for no relational database, just a bit of separation between the service tier and the database, such that most service calls don’t block waiting for the database to be available.
  • Connecting directly to services is a very slow way to retrieve data – it involves querying the database, processing the data into the format to be returned, and then returning it directly from the service instance. Compare this to retrieving the same data, pre-fetched and available via a CDN. The latter is going to be significantly faster, will cut down on bandwidth costs, will reduce load on both services and database since they no longer have to do work for every request for data.
  • Changes submitted to the services have to be applied directly to the database – if the database is offline, or otherwise unavailable, the service call will fail. Even if the data can be written immediately, there is a latency involved which increases the execution time of the service. This means more scaling of the service and slower responses back to the mobile application.

Reading between the lines you might notice that there are two areas that I want to investigate to see if there’s an opportunity to improve data synchronisation for cloud applications:

  1. Data retrieval: If we take the stance that the services won’t retrieve data directly from the database and return it to the mobile application, we need to think about how we can pre-fetch data and publish it out so it can be retrieved via the CDN. Of course, we don’t want to be publishing out the entire dataset into a single file which updates every time there is a change to the database, as this would undo any benefits of using the CDN. CDNs are optimised for immutable data; if you go trying to make changes to a file that’s already been published, you’ll run into a bunch of issues around caching of the data both in the CDN and on the client. Additionally, you don’t want the mobile application to download the entire dataset every time it needs to update. I’ll come back to talk more about the structure of the data but for the moment the assumption is that data will be retrieved and saved into an immutable file that will be placed in blob storage, making it accessible via the CDN.
  2. Data changes: Changes to data are a little harder as the initial standpoint for any developer is that changes should be immediately sent to the database, otherwise the database will be out of date. One of the realisations learnt by a lot of social sites (as they represent some of the largest datasets available) is that they rely on Eventual Consistency. In some data synchronisation cases, eventual consistency isn’t an option but for the other scenarios, it’s important to consider the use of queues to break up the change workflow. For example when a mobile app sends a change to the service, the service can simply queue the change and respond back a successful acknowledgement. When the change gets popped off the queue and the change applied to the database, a new message can go on the queue to indicate the response. When this message is popped off the queue, a notification is sent back to the mobile application indicating that the data has been saved to the database.

It’s been a while since I’ve reviewed synchronisation logic but it’s become evident that there are some interesting options that are now possible with the Azure cloud platform. I want to visit both of these areas in much more detail.