Nick's .NET Travels

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

Windows Hello (Beta) on Lumia 950 XL

Yesterday, after my Lumia 950 XL arrived, I noted that one of the two features I was going to try was Windows Hello. I want to start by saying that I now have this on both my Surface Book and the Lumia 950XL, and I’ve been using it on the former for quite some time now. Windows Hello on the Surface Book absolutely rocks – it’s not as instant sign on as say the Touch ID sign in capability on the iphone, which is virtually instantaneous on the latest iphones/ipads, but it is still relatively quick and definitely hands free. The latter is useful if you don’t have the keyboard attached.

Unfortunately my experience on the Lumia 950 XL has been disappointing at best, frustrating in some cases. I’ve gone in and repeatedly try to improve recognition but despite this Windows Hello only recognises me less than 50% of the time. What’s worse is that after not recognising me a couple of times it stops trying and forces me to use PIN to unlock. It would be good if it would prompt and suggest PIN to unlock, followed by perhaps a suggestion to improve recognition (perhaps to allow for different lighting conditions etc) but this should only be a suggestion, the camera should still try to identify me, especially since my head is in front of the camera and it should be able to at least detect the presence of a head, even if it can’t identify that it’s me.

The disappointing thing is that even when it does recognise me, it’s no quicker than me swiping up and entering my 4 digit PIN, and you look much less of an idiot doing it. I feel that the integration of a finger print reader would have been much better – less chance of you putting your finger in the wrong place and less environment factors to account for. Not to mention the technology is probably cheaper than the camera required to do Windows Hello with a camera.

This bring me to the final point of this post which is that I’ve bought a production device which comes with the RTM build of Windows 10 Mobile. Now of course, Windows is now a service, which means that patches and updates should come through progressively but at this point no updates have come out for regular customers. If you go to Settings and look at setting up Windows Hello, it is clearly marked as Beta…. WTF! Why have I got Beta features on a device I’ve paid a lot of money for? I don’t know when it became acceptable to ship Beta features to end customers but I think it traces back to Google (if you recall Google was in Beta for years before this tag was removed from their service). Beta testing is there for a purpose, to iron out bugs before you ship to end customers. Now that’s not to say that you can’t have some end customers as beta testers, but they should be invited/request to take part, rather than assume that every customer will tolerate unpolished, incomplete or broken features. Microsoft shipping Beta features to end customers just points to why Apple dominates the mobile market and why iOS customers rarely switch to other platforms.

Certifying and Distributing Windows Store Applications to Earlier (ie Non-Supported) Versions of Windows 10 Mobile

In my previous post on Visual Studio 2015 RTM, Universal Windows Platform (UWP) Developer Tools and Debugging on a Windows Phone device I covered modifying the TargetPlatformMinVersion property in the Visual Studio project file in order to deploy your Universal Windows Platform application to a Windows 10 Mobile device. Granted that this post is probably a little too late, since the next build of Windows 10 Mobile is now out (I'm yet to install it), but it is possible to publish your application to the Store so that it can be installed on a non-developer enabled phone.

Now you'd think you'd just be able to create a Store package with the TargetPlatformMinVersion property set to the required value (in this case 10.0.10166.0 to match what I currently have on my device - see the OS Version attribute in the About screenshot below). Unfortunately this is not the case!


If you do attempt to generate a Store package you'll see an error similar to the following image - "10.0.10166.0" is not a supported value for TargetPlatformMinVersion. Please change it on the Project Property page



Ok, so step one is to revert the change to TargetPlatformMinVersion so that you can at least generate a Store package. From the Project menu in Visual Studio, select Store -> Create App Packages (if this option isn't enabled, make sure you have you UWP project selected in Solution Explorer). Follow the prompts to do a Store build - this should generate an .appx file you can work with.

What we're going to do is manually modify the generated package. From the Start menu, select the Developer Command Prompt for VS2015



Change directories to where the .appx file resides. Execute the following command, substituting you .appx filename. This will extract the contents of the .appx file into a sub-folder called "export"
makeappx unpack /nv /p myapplicationpackage.appx /d .\export
Open the AppxManifest.xml file using your text editor of choice. Locate the line that looks similar to the following and replace the MinVersion with the version number you want to target (ie 10.0.10166.0)

<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.10240.0" MaxVersionTested="10.0.10240.0" />
Close and save the updated AppxManifest.xml file. And return to the command prompt and execute the following (again feel free to replace the .appx filename)
makeappx pack /nv /d .\export /p myapplicationpackage-updatedversion.appx
And you're done - submit this package to the Store, and a couple of days later (yes, whilst certification only seems to take a couple of hours, the distribution of UWP apps is very slow at the moment, so expect to wait at least 24hours from when certification is completed) you'll be able to install your application...... of course, all of this could have been saved if you'd just updated to the latest Windows 10 Mobile build, which I'm about to do now!

Visual Studio 2015 RTM, Universal Windows Platform (UWP) Developer Tools and Debugging on a Windows Phone device

If you've upgraded to Visual Studio 2015 RTM with the associated Universal Windows Platform tools, you may have realised that you can't deploy apps to a real Windows Phone that's running the current Windows Insider Preview build for Windows Phone. This is because the version of the SDK, which has a version/minversion of 10.0.10240.0, is higher than what's currently available for the phone. For application development and testing this means using the emulators that ship with the SDK.

Of course, this isn't a great story as lots of developers much prefer debugging on a real device. In fact there are scenarios where a real device is the only way to test some scenarios. I came across the following post that provides a temporary, NON-SUPPORTED solution.

https://social.msdn.microsoft.com/Forums/en-US/46889785-07bd-4e10-9134-e8fa429b1486/uwp-is-it-possible-to-deploy-a-uwp-app-build-in-vs2015rtm-to-windows-phone-running-10010166?forum=wpdevelop

The solution rests on manually changing the TargetPlatformMinVersion property in the UWP project file to be the same as what's running on the phone (in my case 10.0.10166.0). Don't change the TargetPlatformVersion property - doing this will mean that you won't be able to open the project in Visual Studio since that version isn't supported with the SDK.

WARNING: Whilst making this change may mean that you can debug your application on a real device, just be aware that it may through weird errors if you happen to try to access an API that has actually changed between 166 and 240 builds. Your code is still going to be built against the 10.0.10240.0 API set, you're just lying in the package manifest, claiming that your app will run on a previous version.

As you can imagine this has been designed with future versions in mind. If you open the project properties dialog for the UWP application you'll see that on the Application tab there is a Targeting section. In the current SDK there is only one option for the target version and min version. Going forward you can imagine that a future SDK will allow for selection of 10.0.10240.0 (the current version) and a future version (where APIs may have evolved).

 

Windows Phone 8.1, Microsoft Lumia 640XL and the case of the Virtual Hardware Buttons

The Microsoft Lumia 640 and 640XL were one of the first Windows Phone devices to take advantage of the move to on-screen hardware buttons. Rather than the traditional hardware buttons for Back, Start and Search, these devices have software rendered buttons (note that there were previous devices that had the buttons as part of the same glass as the reset of the screen but this isn't the same as having them rendered in software). There were some that didn't like this move (eg http://www.7tutorials.com/reviewing-microsoft-lumia-640-xl-good-smartphone-business-users) but an nice effect of them being software is that they can be dismissed off the screen. This means that the buttons can be swiped away, leaving more screen available for applications.

The unfortunately thing about this is that because this feature shipped as an update to Windows Phone 8.1 there isn't good support for detecting when the available screen size changes, often leaving applications either with controls rendered under the buttons, or with empty screen space under the content of the application (where the buttons used to reside).

Side note: Rudy Huyn in his post, "How to test my app on phone with navigation bar and why it matters," covers how to use the Windows Phone emulator to test applications for this behaviour.

I spent a bit of time this afternoon trying to work out a workable solution to this. The result was a bit hit and miss but the following seems to work:

In order to take advantage of the full screen I added the following lines to the end of the OnLaunched method in the App.xaml.cs file:

var applicationView = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView();
applicationView.SetDesiredBoundsMode(Windows.UI.ViewManagement.ApplicationViewBoundsMode.UseCoreWindow);

The UX of the screen is very basic - it has a background color so that you can see where the page is being rendered and a textbox at the bottom of the screen so that you can see whether an element has been hidden. Note also that the VerticalAlignment of the page is set to Top. This might seem weird but if you don't, as you adjust the Height of the page in accordance with the visible bounds, you'll see the page rendered in the middle of the screen, which is not what you want.

<Page x:Class="AppBarTest.MainPage"
      xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml"
      VerticalAlignment="Top">
    <Page.BottomAppBar>
        <CommandBar>
            <AppBarButton Icon="Accept"
                          Label="appbarbutton" />
            <AppBarButton Icon="Cancel"
                          Label="appbarbutton" />
        </CommandBar>
    </Page.BottomAppBar>

    <Grid Background="LightBlue">
        <TextBox Text="Testing"
                 VerticalAlignment="Bottom"
                 Margin="0" />
    </Grid>
</Page>

The code for this page is where all the hacking happens - essentially it looks to determine how tall the page should be based on the space occluded by the status bar and the input pane. The trick is to make sure this is called anytime something adjusts the visible bounds available to the app.

public sealed partial class MainPage
{
    public MainPage()
    {
        InitializeComponent();
           
        var appView = ApplicationView.GetForCurrentView();
        appView.VisibleBoundsChanged += VisibleBoundsChanged;
    }

    private void VisibleBoundsChanged(ApplicationView sender, object args)
    {
        ResizeMe();
    }

    private void ResizeMe()
    {
        var statusBar = StatusBar.GetForCurrentView();

        var appView = ApplicationView.GetForCurrentView();
        var input = InputPane.GetForCurrentView();
        var newHeight = appView.VisibleBounds.Height + (statusBar?.OccludedRect.Height) ??
                                0 + (input?.OccludedRect.Height) ?? 0;
        if ((input?.OccludedRect.Height ?? 0) <= 0 || newHeight <
this.Height)
        {
            this.Height = newHeight;
        }
    }

Update: You should also attach an event handler to the Got and Lost focus on the TextBox and invoke ResizeMe otherwise there are some scenarios where the TextBox ends up under the virtual buttons

Build it Beta for Windows and Windows Phone

Over the last couple of weeks we’ve done some major work to Build it Beta which will significantly improve and simplify the process of getting Build it Beta installed and setup across Windows and Windows Phone. If this is the first time you’ve heard of Build it Beta, it is a home-grown solution for the deployment of Windows platform applications. The primary scenario that Build it Beta solves, is the need for developers to deploy applications to testers so that they can provide feedback. It does this by leveraging the enterprise deployment capabilities of the Windows platform, where applications can be signed using a enterprise signing certificate and then deployed to devices that trust that certificate.

Supported platforms

The following Windows platforms are supported by Build it Beta for the installation of test applications.

Windows Phone 8.0
Windows Phone 8.1
Windows 8.1
Windows 10 (Phone and desktop)

Supported application platforms

Applications targeting the following platforms are supported by Build it Beta

Windows Phone 7.x (XAP)*
Windows Phone 8.0 (XAP)
Windows Phone 8.1 (XAP)
Windows Phone 8.1 (APPX)
Windows 8.0 (APPX)*
Windows 8.1 (APPX)
Windows 10 UAP (APPX)

*Build it Beta supports signing and deploying applications targeting Windows Phone 7.x and Windows 8.0. However, due to lack of enterprise distribution support in Windows Phone 7.x there is no way to deploy applications to those devices. Windows Phone 7.x applications can only be tested on Windows Phone 8+ devices. The Windows version of Build it Beta targets Windows 8.1 so there is no support for deploying to Windows 8.0 devices. Windows 8.0 applications need to be tested on Windows 8.1+.

Here are some useful links for getting started with Build it Beta

Distribution of Application for the Windows Platform for Testing

Last year I wrote an article for Visual Studio Magazine entitled Enterprise Distribution of Windows Phone Applications which looks at the requirements and steps required to deploy Windows Phone applications. The process for distributing Windows desktop/slate applications is slightly different but essentially involves signing the appx with an appropriate code signing certificate that is trusted by those computers that the application will be distributed to. We’re using these same techniques with Build it Beta to help developers distribute their applications for testing. Recently we’ve done a number of bug fixes and improvements and now have support for Windows Phone 8.0,  Windows Phone 8.1 (Silverlight), Windows Phone 8.1 (Appx), Windows 8.0 and 8.1, and now Windows 10 applications. There is still a bit of work to go in rounding off some of the rough edges but we’re really keen for developers to start using it.

We’ve also just created a new Build it Beta blog where we will be posting a series of post talking about distribution of applications for testing both in the generic sense (covering signing and enterprise distribution) and of course how Build it Beta works. Don’t forget you can follow Build it Beta on Twitter as well.

Disabling the Pinch-Zoom behaviour of the WebBrowser control on Windows Phone

This is an issue that seems to keep coming back to haunt us on various projects where we have to embed web content within a Windows Phone application. One of the best solutions is to modify the CSS of the page being displayed to disable the touch behaviour using the –ms-touch-action (noted that whilst in IE11+ the recommendation is to use the touch-action property but for WP the vendor prefix is still required).

One of the team that I work with came across a post by Colin Eberhardt that handles some of the manipulation events in the visual tree surrounding the actual web content, thereby disabling the pinch-to-zoom behaviour. This technique makes use of Linq to XAML/Visual Tree which is also worth a read

Dynamic Layout with the Windows Platform

Today there have been a number of announcements in regards to the Windows 10 universal app platform, including the availability of the tools preview:

http://channel9.msdn.com/Shows/Inside-Windows-Platform/A-First-Look-at-Building-Windows-10-Universal-Applications

http://blogs.windows.com/buildingapps/2015/03/23/windows-10-developer-tooling-preview-now-available-to-windows-insiders/

http://www.microsoftvirtualacademy.com/training-courses/a-developers-guide-to-windows-10-preview

http://dev.windows.com/en-us/whats-new-windows-10-dev-preview

http://microsoft.github.io/windows/

http://blogs.msdn.com/b/somasegar/archive/2015/03/23/visual-studio-tools-for-windows-10-technical-preview.aspx

Microsoft have been talking for quite some time about Windows 10 being a single platform that developers can target and have applications run across a multitude of different devices ranging from phone, to slate/tablet, to desktop and even up to Xbox and Surface Hub. This has in part been achievable to a less degree with previous iterations of the framework and as developers we’ve learnt to maximise the reuse along the way. However, for the first time a single executable will run across all devices without recompile. Is this the nirvana that we’ve all been looking for? Here are a couple of things to consider:

- There are still going to be device differences – whilst the core will be common, there are extension sdks for different platforms. Developers will have to query for the existence of contracts before invoking specific extension methods.

- Previously there was a forced break between phone and full screen (ignoring split mode) tablet/desktop, which was convenient for designers. Windows 10 introduces a significant challenge for designers as they have to scale up/down the user experience to handle all manner of sizes and shapes.

- The restricted form factors of the past lead themselves well to a page based navigation, although the page sequence often differed between Windows Phone and Windows. With Windows 10 the page based navigation model doesn’t lend itself well to resizing and adapting to different screen sizes.

The last point is worth expanding on. When an application is resized down to the size of a phone the experience should be similar to a phone application where navigation appears to be page based, including a back button to navigate back between pages. As the application is resized up, initially it would be acceptable to simply scale the size or amount of content being shown. However, at some point there is too much screen real estate available which is either being wasted (voids of empty space) or content is oversized (assuming content continues to scale). Now a different approach is required which will involve presenting more content on the screen. This additional content, which may have been on a different page when on the phone or smaller layout, now needs to be rendered on the same page – this completely breaks the page lifecycle model that most applications are based on, leading to an open question as to how best to handle resizing of applications?

Breaking up the User Experience to Allow for Reuse across Windows and Windows Phone

Last post I talked about the basic flow of the Real Estate Inspector application (overly simplified of course as it’s a sample application) and I eluded to the need to have a different user experience for different form factors and to allow the user experience to adapt as screen size varies. This problem is going to escalate as we go into the Windows 10 timeframe where a single application will need to deal with a number of different form factors.

The first page to deal with is the login page – the big difference here is that on Windows Phone it’ll be a separate page, whereas on a larger screen it’ll be displayed as a modal style dialog across the current page. In both cases the login page/view will double up as a profile page for the currently signed in user, as well as perhaps any settings that may apply to the current user. Either way this is going to be a simple view that doesn’t need to vary substantially between form factors.

The main page of the application is relatively straight forward as it will simply show the properties that the user has access to. The only difference might be that when the display is portrait (ie similar ratio to a typical phone) the properties could be in a list, whereas when there is more screen real estate the properties can be expanded into a tile array. One of the issues associated with tile array is that there isn’t an implied order; well this isn’t quite true but it’s harder for the user to know whether the order is across-then-down, or down-then-across, at least until they attempt to scroll the screen and then it becomes easier to follow. Luckily in this case the properties aren’t in any particular order.

image  image

If we did decide that properties needed to be ordered, we might adopt a layout similar to the new Photos app on Windows 10 where it uses vertical grouping to imply some level of ordering. For example properties could be order by suburb, or could be ordered by upcoming inspection times (date or week groupings)

image

Now comes the hard part – what does the Property page look like. A Property has both details of the Property itself, as well as a list of inspections that have been carried out. Each inspection will then have to be made up of any number of rooms/areas where inspection information needs to be recorded. The experience on the phone might be:

- User clicks on a Property on the main page

- Property is displayed in a pivot with the details making up any number of pivot items, and the list of inspections being on a separate pivot item.

- Clicking an inspection opens up the inspection, showing a summary of the inspection (eg who did the inspection and date/time) and then a list of inspection rooms/areas – this again could be a pivot

- The inspection room/area would be a simple page made up of a number of form fields.

This layout also works well on tablet/desktop when the application has been reduced to a rough 16:9 portrait layout. However, here’s where things start to get more complex – as the screen size and orientation changes the challenge is how best to use the available real estate. The following image illustrates how expanding the page width or height can lead to unused screen space. I’m not implying you always have to make use of every bit of screen real estate but you also don’t want your application to feel like it is wasting screen space.

image

Starting with the tiled layout on the main screen, if the user taps on one of the Properties there are really three options:

- There is enough space to present a vertical list of Properties, Property details and list of Inspections as three columns

- There is enough space to present a horizontal grid of Properties (1 or two deep), with Property details and list of inspections as two columns under

- There isn’t enough space to present the list of Properties, in which case only the Property details are displayed, along with a Back button to allow for navigation back to the list of Properties.

Here you can see the break down of the developer experience already – we have three distinct user experiences, two of which are done on the same page, whilst the third would normally involve a page navigation (similar to what would happen on the phone).

The complexity escalates even further when you consider that the user might decide to dynamically resize the layout, going from just Property details out vertically where the grid of properties appear at the top, and then horizontally where the list of properties re-orientates to a vertical list, making better use of the screen size. I don’t see an easy way to deal with this dynamic resize operations given the relatively primitive controls the Windows platform offers out of the box.

Navigation Flow for Real Estate Inspector Application for Windows Phone

In building out the pages for the Real Estate Inspector application the first step is to think through the core pages that make up the application. The following navigation flow diagram illustrates the four pages that would make up the phone application. In this case each of the four nodes represent pages or views that you’d expect to see within the application.

image

However, if we consider what might happen on a slate/tablet/desktop experience, not all of these nodes has to be a dedicated page. For example, the Login might be a popup/modal style dialog that appears across the centre of the screen. In fact, with Windows, this is exactly how the Web Authentication Broker appears. There may also be other non-core views that are not represented on here which will features as pages/views on phone but as nested views or modal style dialogs on the larger screen. For example viewing a photo may be a full screen, separate page, experience on phone. On larger devices it may be that this is again a popup/modal style interface.

One thing that can be noted from this diagram is that the Login can be accessed from any of the nodes. Whilst the initial experience will be to navigate to Login from the Home page on first run, at any point there after, if synchronisation fails due to an authentication issue, it’s important that the user is prompted to authenticate immediately to ensure they can continue to operate. This doesn’t need to be a blocking operation as it may be that the user needs to continue to work, despite authentication failing. It is however, important that some rules are in place to ensure the user does update their authentication information (ie enter correct password) within a nominated period for security reasons. After all, there is the scenario where the user no longer works for the organisation in which case their account should both be locked (ie can’t authenticate) and access should be prevented to the application.

Data Synchronization and Sqlite Data Model For Multi-User Scenarios

Most consumer application are built to either run anonymously (ie not captured information about who the user is) or they are designed with a single user in mind (think the Facebook application – whilst you can log out, typically to stay logged in, even across multiple sessions of running the application). Enterprise or Line of Business applications, particularly on slate/tablet devices are often multi-tenanted with users picking up the nearest device to them, running the app, signing in and getting to work. With this in mind the real estate inspector application has been architected so far to allow for login and switching between users. However, the local caching has been to a single Sqlite database which resides in the users application data folder. If users switch Windows profile then there isn’t an issue but this doesn’t work for devices where there isn’t a notion of user specific data folders. In this case all users will access the same database, which will result in synchronization issues or users seeing data that isn’t assigned to them.

A simple solution would be to simply create a different database for each user. However, if there is data that is common across all users (Eg property types) this will be synchronized into each database. An alternatively approach is to have a common or master database which is used to synchronise data that is common across all users, then to have individual user databases that just contain the user specific data.

View Models for Split Frame Windows

In my previous post I talked about adapting the application UX for varying screen size. Currently the navigation model relies on a one to one mapping between pages and view models. However, with the need to support a split screen (eg list on left, details on right) and to continue to support the List/Details page model without too much rework, I need a mechanism for supporting multiple view models. The simplest approach is to again match what I did with the UI layer – the ListAndDetailsPage would have its own view model eg ListAndDetailsViewModel which would contain references to instances of the ListViewModel and DetailsViewModel (these would typically be used to match the ListPage and DetailsPage).

This approach could be taken a step further by having separate view models for the ListControl and DetailsControl – these could be based on a different base view model as they would only ever be created as child view models (ie you can’t navigate to them). In the coming posts I’m going to look at the layout of the real estate inspector sample app and build out the UX using this approach.

Navigation, View Models, Pages, Frames and Universal Windows Applications

Over the past couple of month Microsoft has been laying the groundwork to get developers excited about the upcoming universal application model that will ship with Windows 10. The promise of a single executable that will just run anywhere seems to be the holy grail. However, just because an application will run anywhere, on any devices, doesn’t mean that the user experience is optimized. Take for example a simple list-details windows phone application which presents a list of items, which, when an item is tapped, navigates to a new page with the details of the item. On a desktop with a large screen it doesn’t make sense to navigate to a separate page in order to display the details of the item. Instead, the screen can be split with the list on the left and the details of the selected item displayed on the right.

The simple app navigation model I discussed previously assumes simple navigation between view models, and thus between pages on the Windows platform. However, it’s not that simple; as we just saw instead of navigating to a new page, the selected item is presented in full on the right side. This means we need to contemplate a more complex set of navigation rules, allowing for different navigation paths through the application dependent on available screen real estate. In fact to handle the scenario with a list on the left and details on the right, it may be necessary to consider sub-views with corresponding sub view-models.

Taking this example, let’s assume that we start off with two pages: ListPage and DetailsPage. When we have more space we want to extend the ListPage to include details for the selected item. It doesn’t make sense to duplicate the layout, which would result in a maintenance headache. Instead what we can do is to start extracting portions of the UI into usercontrols that can be reused. For example we might have ListControl, which displays the list of items, and DetailsControl, which not surprisingly displays the details of the item. Clearly these map to the existing ListPage and DetailsPage but now in the case of larger screens we have two options: we can either add the DetailsControl to the ListPage so that, space permitting, the details can be displayed on the right; or, we can create a completely different ListAndDetailsPage which as you’d imagine has both the ListControl and DetailsControl. Now a distinction could be made between phone and desktop platforms to navigate to the appropriate page.

The last challenge is how to handle resizing Windows – in Windows 8/8.1 this problem didn’t really exist. Well it did if you included snap/split mode but very few developers really went to any lengths to refactor their UX and it really only resized the display width-wise. In Windows 10, users will be able to more dynamically adjust the size of the Window and it is up to us application developers/designers to determine how the application behaves. Take the list-details example – with a minimal window, the application should almost mirror the UX of the phone. However, since we have the ListAndDetailsPage the UX will have to adjust the layout, rather than simply navigating to a new page.

There’s clearly a lot to think about and the holy grail of a single application is still going to take a lot of refinement to get right – time to find yourself a great UX person to add to the team!

Communication and Synchronization using Background Tasks with Windows and Windows Phone 8.1

In an earlier post I covered creating a background task for Windows platform applications that would allow for synchronization in the background, triggered by change in Internet availability. However, one thing I didn’t cover is what happens when the application is in use, in this case, not only might the user be interacting with the data (loading and writing new records), they might have even forced a synchronization within the application. For this reason it may be necessary to prevent background synchronization whilst the foreground application is being used.

If you haven’t worked with Windows/Windows Phone 8.1 before the OnActivated method might be confusing in the Application class – it’s not the same as the Activated/Deactivated pair from Windows Phone 7x/8.0 where they occurred reliably when the application went into the background. For Windows/Phone 8.1 you need to look at the Window VisibilityChanged event to detect when the Window goes into the background (note that there is an issue with this on Windows 10 where it isn’t triggered when you switch to another application as all applications are windowed by default).

protected override void OnWindowCreated(WindowCreatedEventArgs args)
{
    args.Window.VisibilityChanged += WindowVisibilityChanged;
}

In the event handler I’m going to take ownership of a named Mutex when the Window is visible, and release it when the Window is no longer visible:

private static Mutex backgroundMutex = new Mutex(false,"BackgroundSync");
private async void WindowVisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs e)
{
    if (e.Visible)
    {
        backgroundMutex.WaitOne();

        await ReregisterTasks();
    }
    else
    {
        backgroundMutex.ReleaseMutex();
    }
}

You’ll notice that after taking ownership of the Mutex I then reregister my background task:

private async Task ReregisterTasks()
{
    try
    {
        BackgroundTaskManager.UnregisterBackgroundTasks("Background Sync Task", true);
        BackgroundTaskRegistration taskReg =
            await BackgroundTaskManager.RegisterBackgroundTask(typeof(SyncTask).FullName,
                "Background Sync Task",
                new SystemTrigger(SystemTriggerType.InternetAvailable, false),
                null);
    }
    catch (Exception ex)
    {
        // Swallow this to ensure app doesn't crash in the case of back ground tasks not registering
        Debug.WriteLine(ex.Message);
    }
}

The reason for this is that we want to cancel any running background task (the “true” parameter passed into the UnregisterBackgroundTasks call).

In the background task I have a Mutex with the same name (Named Mutexes are shared across processes so a great way to communicate between foreground/background tasks). At the beginning of the Run method I attempt to acquire the Mutex: if this succeeds I know my foreground application isn’t visible; if this fails (which it will do immediately since I specified a wait time of 0) it will simply return from the task as we don’t want to sync whilst the foreground application is visible. If the background task is going to run, I immediately release the Mutex which will ensure that if the foreground application is made visible, or launched, it won’t be blocked waiting to acquire the Mutex.

private static Mutex foregroundMutex = new Mutex(false,"BackgroundSync");
public async void Run(IBackgroundTaskInstance taskInstance)
{
    try
    {
        if (!foregroundMutex.WaitOne(0)) return;
        foregroundMutex.ReleaseMutex();
        // do the rest of background task

It’s important within your background task to override and handle the OnCanceled method so that if the background task is executing when it is unregistered, the task can be cancelled gracefully.

Adding Logging to Client Applications using MetroLog not NLog

I wanted to add some logging to my set of applications and was somewhat disappointed to discover the complete lack of PCL support in NLog. After a quick search to find out what others are using I came across MetroLog which seems to be very similar in a lot of regards to NLog (in fact they claim the API surface is very similar indeed). I went to install the NuGet package…

image

and noticed that my Core library (a PCL) wasn’t in the list. Clearly my PCL profile doesn’t match one of the supported profiles which is a bit painful. However, it does support all my client application types so I was happy at least to use MetroLog.

image

I did have a couple of issues installing the NuGet package, namely Visual Studio decided to crash mid way through installing the packages. This meant I had to manually install Microsoft.Bcl.Compression which is a dependency for the Windows Phone 8.0 project, and then uninstall and reinstall the support for the Windows and Desktop projects.

After all this I was building successfully again so it was time to think about how to structure the logging support. Clearly with logging I want it to be a simple as possible and yet accessible virtually anywhere within the application. I want to define a service that is available within my Core library in a similar way to my IDataService and ISyncService implementation. I also wanted the log output to be written out to a sqlite database file for ease of access (there are plenty of third party tools capable of viewing sqlite db files) but rather than use the SqliteTarget that comes with MetroLog I felt I had to write my own (as you do). Luckily this whole process is relatively simple.

I start by creating an ILogWriterService interface which will provide the low level API for writing a LogEntry to a local Mobile Service sqlite table (I’m going to use the same process that is used to cache my synchronized data, except for the time being at least, the data won’t be synchronized anywhere).

public interface ILogWriterService
{

    IMobileServiceSyncTable<LogEntry> LogTable { get; }
    Task Initialize();
}

public class LogEntry : BaseEntityData
{
    public DateTime LogDateTime { get; set; }
    public string Entry { get; set; }
}

public class LogWriterService : ILogWriterService
{
    private readonly MobileServiceClient mobileService = new MobileServiceClient(Constants.MobileServiceRootUri);

    private IMobileServiceClient MobileService
    {
        get { return mobileService; }
    }

    public IMobileServiceSyncTable<LogEntry> LogTable
    {
        get { return MobileService.GetSyncTable<LogEntry>(); }
    }

    public async Task Initialize()
    {
        var data = new MobileServiceSQLiteStore("log.db");
        data.DefineTable<LogEntry>();

        await MobileService.SyncContext.InitializeAsync(data, new MobileServiceSyncHandler());
    }
}

Next I define the high level service interface, ILogService:

public interface ILogService
{
    void Debug(string message);

    void Exception(string message, Exception ex);
}

So far, all of these classes have been in the Core library. However, the implementation of the ILogService has to be in the Shared.Client project as it needs to be used by all the client projects.

public class LogService : ILogService
{
    public ILogWriterService Writer { get; set; }

    public ILogger Logger { get; set; }

    public LogService(ILogWriterService writer)
    {
        Writer = writer;
        var target = new MobileServiceTarget(Writer);

        LogManagerFactory.DefaultConfiguration.AddTarget(LogLevel.Debug, target);

        Logger = LogManagerFactory.DefaultLogManager.GetLogger("Default");
    }

    public void Debug(string message)
    {
        Logger.Debug(message);
    }

    public void Exception(string message, Exception ex)
    {
        Logger.Error(message, ex);
    }
}

As you can see the implementation sets up the MetroLog logger but uses a custom MobileServiceTarget as the destination. This is implemented as follows:

public class MobileServiceTarget : Target
{
    public ILogWriterService Writer { get; set; }
    public MobileServiceTarget(ILogWriterService writer)
        : base(new SingleLineLayout())
    {
        Writer = writer;
    }

    private bool InitCompleted { get; set; }
    protected async override Task<LogWriteOperation> WriteAsyncCore(LogWriteContext context, LogEventInfo entry)
    {
        try
        {
            if (!InitCompleted)
            {
                await Writer.Initialize();
                InitCompleted = true;
            }
            var log = new LogEntry { LogDateTime = DateTime.Now, Entry = entry.ToJson() };
            await Writer.LogTable.InsertAsync(log);
            return new LogWriteOperation(this, entry, true);
        }
        catch (Exception ex)
        {
            return new LogWriteOperation(this, entry, false);
        }
    }
}

I of course need to register the implementations with Autofac:

builder.RegisterType<LogWriterService>().As<ILogWriterService>();
builder.RegisterType<LogService>().As<ILogService>();

And the last thing is a static helper class that makes logging for two core scenarios really easy:

public static class LogHelper
{
    public static void Log<TEntity>(TEntity entity, [CallerMemberName] string caller = null)
    {
        var json = JsonConvert.SerializeObject(entity);
        Log(typeof(TEntity).Name + ": " + json, caller);
    }

    public static void Log(string message = null, [CallerMemberName] string caller = null)
    {
        try
        {
            InternalWriteLog("[" + caller + "] " + message);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
    }

    public static void Log(this Exception ex, string message = null, [CallerMemberName] string caller = null)
    {
        try
        {
            Debug.WriteLine("Exception ({0}): {1}", caller, ex.Message);
            InternalWriteException(caller + ": " + message, ex);
        }
        catch (Exception ext)
        {
            Debug.WriteLine(ext.Message);
        }
    }

    private static ILogService logService;

    private static ILogService LogService
    {
        get
        {
            if (logService == null)
            {
                logService = ServiceLocator.Current.GetInstance<ILogService>();

            }
            return logService;
        }
    }

    private static void InternalWriteLog(string message)
    {
        try
        {

            LogService.Debug(message);
        }
        catch (Exception ext)
        {
            Debug.WriteLine(ext.Message);
        }
    }

    private static void InternalWriteException(string message, Exception ex)
    {
        try
        {
            LogService.Exception(message, ex);
        }
        catch (Exception ext)
        {
            Debug.WriteLine(ext.Message);
        }
    }
}

The first scenario is a simple string output eg:

LogHelper.Log("Startup complete");

The second is logging the output of an Exception:

try
{
   …
}
catch (Exception ex)
{
    ex.Log();
}

Note that the Exception logging also does a Debug.WriteLine which is convenient during development to pick up any issues in the Output window.

Blend Designer Error Due to Service Locator

I was just about to get started using Blend to layout a page and noticed that there was an error in the Results pane in Blend, stating that the ServiceLocatorProvider must be set.

image

I was pretty certain that this was something I was doing during startup but clearly that code isn’t being run correctly at design time. Turns out I don’t really care at design time since I’m going to predominantly use design time data. This means that in the ViewModelLocator constructor I can simply exit if it’s being invoked at design time. Unfortunately the usual design mode property that you can query to determine if the code is being run at design time doesn’t exist in the view model locator scope. Luckily an alternative is to simply query if the service locator provider has been set:

public ViewModelLocator()
{
    if (!ServiceLocator.IsLocationProviderSet) return;
    DataService = ServiceLocator.Current.GetInstance<IDataService>();
    SyncService = ServiceLocator.Current.GetInstance<ISyncService>();
    NavigateService = ServiceLocator.Current.GetInstance<INavigateService>();
}

Synchronizing in a Background Task

Now that we have implementations for IDataService and ISyncService I can update the backgounrd task for the Windows platform applications to perform synchronization in the background. To begin with I need to reference the Autofac libraries (including the Microsoft common service locator and extensions libraries) by adding the RealEstateInspector.Background in NuGet package manager

image

 

The next thing is to update the Run method of the background task so that it looks for a current access token and uses it to initialise the data service.

public async void Run(IBackgroundTaskInstance taskInstance)
{
    try
    {
        var cost = BackgroundWorkCost.CurrentBackgroundWorkCost;

        var authContext = new AuthenticationContext(Constants.ADAuthority);
        if (authContext.TokenCache.ReadItems().Count() > 0)
        {
            authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().First().Authority);
        }

        var authResult =
            await
                authContext.AcquireTokenSilentAsync(Constants.MobileServiceAppIdUri,
                Constants.ADNativeClientApplicationClientId);
        if (authResult != null && !string.IsNullOrWhiteSpace(authResult.AccessToken))
        {
            var dataService = ServiceLocator.Current.GetInstance<IDataService>();
            var syncService = ServiceLocator.Current.GetInstance<ISyncService>();

            await dataService.Initialize(authResult.AccessToken);

            if (cost == BackgroundWorkCostValue.High)
            {
                await syncService.ForceUpload();
            }
            else
            {
                await syncService.Synchronise(true);
            }
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }
    finally
    {
        if (deferral != null)
        {
            deferral.Complete();
        }
    }
}

Depending on the cost of the background task I either want the task to force an upload of pending updates (if high cost), or do a full synchronisation.

Navigation Service for Cross Platform Page/View Navigation from View Model

I already have a solution for allowing the view model to jump back onto the UI thread using the UIContext. However, I currently don’t have a mechanism that will allow one view model initiate navigation to a new page/view. What I want is the ability for one view model to request navigation by specifying the destination view model. Of course, this needs to work cross platform. Let’s take a look at the basics of how this could work – there are essentially two strategies that most mvvm style navigation frameworks use: The first is by convention where the lookup for the destination page/view is based on the name of the target view model; the second is by defining a mapping between view models and the corresponding page/view. In this case I’m going to go with the latter – In the Core library I define a couple of interfaces and an abstract implementation:

public interface INavigateService
{
    void Navigate<TViewModel>() where TViewModel : IDataViewModel;
}

public interface INativeNavigateService<TView> : INavigateService
    where TView : class,new()
{
    void Register<TViewModel, TViewType>() where TViewType : TView;
}

public abstract class CoreNavigateService<TView> : INativeNavigateService<TView> where TView : class, new()
{
    private readonly IDictionary<Type, Type> viewDictionary = new Dictionary<Type, Type>();

    protected Type ViewType<TViewModel>()
    {
        Type viewType = null;
        viewDictionary.TryGetValue(typeof(TViewModel), out viewType);
        return viewType;
    }

    public void Register<TViewModel, TViewType>() where TViewType : TView
    {
        viewDictionary[typeof(TViewModel)] = typeof(TView);
    }

    public void Navigate<TViewModel>() where TViewModel : IDataViewModel
    {
        var navType = ViewType<TViewModel>();
        NavigateToView(navType);
    }

    protected abstract void NavigateToView(Type viewType);
}

Next, in the client projects, I define a class that inherits from CoreNavigateService and implements the NavigateToView method. Here is the Windows Platform implementation:

public class WindowsPlatformNavigationService : CoreNavigateService<Page>
{
    protected override void NavigateToView(Type viewType)
    {
        (Window.Current.Content as Frame).Navigate(viewType);
    }
}

The ApplicationStartup method now looks like:

public void ApplicationStartup()
{
    CoreApplication.Startup(builder =>
    {

        builder.RegisterType<SignalRFactory>().As<ISignalR>();
#if NETFX_CORE
        builder.RegisterType<UniversalUIContext>().As<IUIContext>();

        builder.RegisterType<WindowsPlatformNavigationService>().SingleInstance().As<INavigateService>();
#endif
    });

    var navService = ServiceLocator.Current.GetInstance<INavigateService>() as WindowsPlatformNavigationService;

#if NETFX_CORE
    navService.Register<MainViewModel,MainPage>();
    navService.Register<SecondViewModel,SecondPage>();
#endif
}

Both the IDataViewModel, BaseViewModel and ViewModelLocator need to be extended to include an INavigateService property called NavigateService. Now from within the view model, navigation can be invoked by calling NavigateService.Navigate<SecondViewModel>()

Adding a Background Task to the Windows Platform Applications

At some point you’re likely to want to run code in the background – this might be to update live tiles, or to do periodic synchronization of data. In this post I’ll add a background task to the Windows platform applications. I’ll start by adding a new Windows Runtime Component to the solution.

image

As a Windows RT component there are some additional restrictions on the definition of types and the way methods are exposed. However, I can still add a reference to the background project to the Core library of the application. As the Core library encapsulates all the logic for the application this should be sufficient to perform background operations such as synchronizing data or updating tile contents.

Next I want to add a reference from the Universal applications (Windows and Windows Phone) to the background task project. Once done, it’s time to create the actual task that will be invoked in the background. I’ll replace the default Class1.cs with SyncTask.cs with the following templated structure:

public sealed class SyncTask : IBackgroundTask
{
    private BackgroundTaskCancellationReason cancelReason = BackgroundTaskCancellationReason.Abort;
    private volatile bool cancelRequested = false;
    private BackgroundTaskDeferral deferral = null;
    //
    // The Run method is the entry point of a background task.
    //
    public async void Run(IBackgroundTaskInstance taskInstance)
    {
        try
        {
            Debug.WriteLine("Background " + taskInstance.Task.Name + " Starting...");

            //
            // Get the deferral object from the task instance, and take a reference to the taskInstance;
            //
            deferral = taskInstance.GetDeferral();
            //
            // Associate a cancellation handler with the background task.
            //
            taskInstance.Canceled += OnCanceled;

            //
            // Query BackgroundWorkCost
            // Guidance: If BackgroundWorkCost is high, then perform only the minimum amount
            // of work in the background task and return immediately.
            var cost = BackgroundWorkCost.CurrentBackgroundWorkCost;

            if (cost == BackgroundWorkCostValue.High)
            {
                // Only push changes
            }
            else
            {
                // Do full sync
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
        finally
        {
            if (deferral != null)
            {
                deferral.Complete();
            }
        }
    }

    //
    // Handles background task cancellation.
    //
    private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
    {
        //
        // Indicate that the background task is canceled.
        //
        cancelRequested = true;
        cancelReason = reason;
        Debug.WriteLine("Background " + sender.Task.Name + " Cancel Requested...");
    }
}

I also need to define this task as a background task in the Declarations section of the project manifest files. In this case we’re going to be triggering the background task based on a system event.

image

Lastly, the background task needs to be registered. For this I’m using this BackgroundTaskManager class which wraps the registration process for tasks.

public class BackgroundTaskManager
{
    /// <summary>
    /// Register a background task with the specified taskEntryPoint, name, trigger,
    /// and condition (optional).
    /// </summary>
    /// <param name="taskEntryPoint">Task entry point for the background task.</param>
    /// <param name="name">A name for the background task.</param>
    /// <param name="trigger">The trigger for the background task.</param>
    /// <param name="condition">An optional conditional event that must be true for the task to fire.</param>
    public static async Task<BackgroundTaskRegistration> RegisterBackgroundTask(String taskEntryPoint, String name, IBackgroundTrigger trigger, IBackgroundCondition condition)
    {
        BackgroundExecutionManager.RemoveAccess();
        var hasAccess = await BackgroundExecutionManager.RequestAccessAsync();
        if (hasAccess == BackgroundAccessStatus.Denied) return null;

        var builder = new BackgroundTaskBuilder();
        builder.Name = name;
        builder.TaskEntryPoint = taskEntryPoint;
        builder.SetTrigger(trigger);
        BackgroundTaskRegistration task = builder.Register();
        Debug.WriteLine(task);

        return task;
    }

    /// <summary>
    /// Unregister background tasks with specified name.
    /// </summary>
    /// <param name="name">Name of the background task to unregister.</param>
    /// <param name="cancelRunningTask">Flag that cancels or let task finish job</param>
    public static void UnregisterBackgroundTasks(string name, bool cancelRunningTask)
    {
        //
        // Loop through all background tasks and unregister any with SampleBackgroundTaskName or
        // SampleBackgroundTaskWithConditionName.
        //
        foreach (var cur in BackgroundTaskRegistration.AllTasks)
        {
            if (cur.Value.Name == name)
            {
                cur.Value.Unregister(cancelRunningTask);
            }
        }
    }
}

The actual registration is done when the application starts. In this case I’m going to cheat a little and include it in the OnNavigatedTo for the MainPage:

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

    try
    {
        BackgroundTaskManager.UnregisterBackgroundTasks("Background Sync Task", true);
        BackgroundTaskRegistration taskReg =
            await BackgroundTaskManager.RegisterBackgroundTask(typeof(SyncTask).FullName,
                "Background Sync Task",
                new SystemTrigger(SystemTriggerType.InternetAvailable, false),
                null);
    }
    catch (Exception ex)
    {
        // Swallow this to ensure app doesn't crash in the case of back ground tasks not registering
        Debug.WriteLine(ex.Message);
    }
}

Notice that this task is registering interest in the InternetAvailable trigger, allowing the background task to be invoked whenever connectivity changes. Note that this process works for both Windows and Windows Phone Universal projects.

Update:

What I forgot to include here is that if you want tasks to run in the background on the Windows platform you need to make them lock screen enabled. To do this set the “Lock screen notifications” to either Badge or Badge and Tile Text.

image

This will cause a couple of red circles indicating issues with the configuration of the application. The first is that you need to specify either location, timer, control channel or push notifications in the Declarations tab – I’ve chosen to check the push notification checkbox

image

The other requirement is a badge logo – I’ve only specified one of the three options. I’d recommend providing all three if you are serious about delivering a high quality application.

image

Update 2:

When it actually came to run this I must confess I ran into an issue with a typo. Back on the second screenshot an observant reader would have noticed the spelling mistake on the namespace RealEstateInspector. When you attempt to register the service I saw something similar to the following:

image

Full exception details:

System.Exception occurred
  HResult=-2147221164
  Message=Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))

Storing the Big Stuff in Blob Storage

Often mobile applications need to store and retrieve large object data, typically photos and video. This is where Azure blog storage comes into play. In order to write into blob storage you need an access key. However, you’d never distribute an actual access key out to a mobile application, even temporarily, as it’s a really bad idea – if someone gets hold of the access key they have access to everything stored in your blob storage. Luckily blob storage has the notion of shared access signatures which you can think of as short term access passes to blob storage. These are typically created using a full access key and as such this operation is done service side.

I’m going to create a dedicated API just for granting shared access signatures to specific containers (which you can think of as single level folders). In this case the containers will be created with public read access on the contents – since the list of blobs per container will be protected and clients will still need a shared access signature in order to write to containers, this should be ample security for a large proportion of application scenarios.

I’ll start off by creating a new Storage area within the Azure management portal.

image

Once created you’ll need to record the storage account name (realestateinspector) and the storage account access key. Add these values into the appSettings section of the web.config file for the Azure Mobile Service

<appSettings>

  <add key="STORAGE_ACCOUNT_NAME"
       value="realestateinspector" />
  <add key="STORAGE_ACCOUNT_ACCESS_KEY"
       value="LxWu0q2UvQ7ddxXvIP3UfV4ozDkLpgaSkUx------------------------------------33WBYHTpTrAGaHjLoynH+61ng==" />

I’ll create a new controller in my Azure Mobile Service based on the Custom Controller item template

image

The bulk of this api controller sits within a single GET operation:

[AuthorizeLevel(AuthorizationLevel.User)]
public class SharedAccessSignatureController : ApiController
{
    public ApiServices Services { get; set; }

    public async Task<string> Get(string containerToAccess)
    {
        var sas = string.Empty;

        if (!string.IsNullOrEmpty(containerToAccess))
        {
            // Try to get the Azure storage account token from app settings. 
            string storageAccountName;
            string storageAccountKey;

            if (Services.Settings.TryGetValue("STORAGE_ACCOUNT_NAME", out storageAccountName) &&
                Services.Settings.TryGetValue("STORAGE_ACCOUNT_ACCESS_KEY", out storageAccountKey))
            {
                // Set the URI for the Blob Storage service.
                var blobEndpoint = new Uri(string.Format("
https://{0}.blob.core.windows.net", storageAccountName));

                // Create the BLOB service client.
                var blobClient = new CloudBlobClient(blobEndpoint, new StorageCredentials(storageAccountName, storageAccountKey));

                // Create a container, if it doesn't already exist.
                var container = blobClient.GetContainerReference(containerToAccess);
                await container.CreateIfNotExistsAsync();

                // Create a shared access permission policy.
                var containerPermissions = new BlobContainerPermissions();

                // Enable anonymous read access to BLOBs.
                containerPermissions.PublicAccess = BlobContainerPublicAccessType.Blob;
                container.SetPermissions(containerPermissions);

                // Define a policy that gives write access to the container for 1h
                var sasPolicy = new SharedAccessBlobPolicy()
                {
                    SharedAccessStartTime = DateTime.UtcNow,
                    SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(59).AddSeconds(59),
                    Permissions = SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Read
                };

                sas = container.GetSharedAccessSignature(sasPolicy);
            }
        }

        return sas;
    }
}

If you change the AuthorizationLevel to Anonymous you can run up this controller and use Fiddler to generate the shared access signature by invoking a GET on (eg http://localhost:51539/api/SharedAccessSignature/test, where test is the name of the container we’re requesting access to. If you want to check that the container has been created and the appropriate security set, you can use the CloudBerry Explorer for Azure Blob Storage.

image

After entering credentials you can immediately see the folders in your blob storage which will in this case have the container “test” which was created when I made the request to the SharedAccessSignature service.

image

You can also use Fiddler to prepare and launch a query – don’t forget to switch the AuthorizationLevel back to User before deploying your services otherwise anyone will be able to access content from your blob storage.