The new background features in Windows 10

If you already have some experience in developing Universal Windows apps for Windows and Windows Phone 8.1, you should already be familiar with the “application lifecycle” concept. Compared to the traditional desktop model, where the application lifecycle is quite simple (basically, one app is able to run and perform tasks until it’s closed), in the mobile world things are a bit different. A mobile device like a smartphone, in fact, needs to handle many requirements which aren’t common in the desktop world, like battery usage, limited available memory, etc.

Consequently, Universal Windows apps (both on 8.1 and 10) use a different lifecycle model, which can be summarized with the following image:

 

clip_image002

 

When an application is opened, it enters into a state called running: in this state, it’s able to use memory, CPU, sensors and whatever feature is available on the device. As soon as the app is suspended (because the user has pressed the Start button or has tapped on a notification sent by another application), after 5 seconds the process is “frozen” in memory. It means that the process will be kept in the device’s RAM memory, but it won’t be able to perform any operation. As such, every device’s resource (CPU, the camera, sensors, etc.) will be available to every other application that the user will decide to launch next. When the user decides to return to our application, the resuming event is triggered: the process is awaken and the application can use again all the device’s resources.

It may happen, however, that the resources are running low: for example, the user starts to open a lot of applications or he may have suspended one or two apps which use a lot of memory (like a game). In this case, when a new application is opened, the device may not have enough memory to manage it: consequently, the operating system has the chance to terminate the older applications to free some memory. In this scenario, it’s the developer’s job to save the state of the application, during the suspension phase, in order to restore it in case the app is reopened after a termination. The goal of this approach is to give to the user the impression that the app has never been closed: the termination by the operating system should be completely transparent for him.

Perform operations in background: background tasks

As you can imagine after reading how the application’s lifecycle works, Universal Windows apps don’t have the chance to perform operations when they’re suspended. The process, in fact, is “frozen” and, as such, it can’t perform any activity which involves the usage of CPU, network, etc.

To allow developers to handle the requirement to perform, somehow, some operations even when the app is suspended, the Windows Runtime has introduced the concept of background task. They are separate projects from the main one that contains the application, but they belong to the same solution and they access to the same app’s context (so, for example, a background task can access to the same local storage used by the application). Background tasks are usually made by a single class, which contains the code that is executed when it’s scheduled by operating system, even if the main application isn’t running.

Here is a sample definition of a background task:

using Windows.ApplicationModel.Background; 

namespace Tasks 
{ 
    public sealed class ExampleBackgroundTask : IBackgroundTask 
    { 

        public void Run(IBackgroundTaskInstance taskInstance) 
        { 

        } 

    } 
} 

A background task is made by a class, which implements the IBackgroundTask interface and manages a method called Run(), which is invoked when the task is activated.

Background tasks are projects which type is Windows Runtime Component and they’re connected to the concept of trigger, which are events that you can subscribe to invoke a background task. There are many types of triggers in Windows Runtime: they can be used to manage periodic requirements (for example, if the task needs to run every 30 minutes), system events (for example, the user has locked / unlocked the device) or the communications with other devices (there is a set of triggers to interact with Bluetooth Low Energy devices).

I won’t go deep about background tasks in this post, since the way they work has unchanged moving from Windows 8.1 to Windows 10. You will find a wide set of new triggers, but the base concepts that drive the development are the same. If you’re interested into this subject, you can refer to the MSDN documentation which is available at https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh977056.aspx

Keep the application active when it’s suspended

The new feature added in Windows 10, which I’m going to detail in this post, is the ExtendedExecutionSession class, which can be used to support two new scenarios:

  1. The application needs to save some data or complete a pending operation before it’s suspended and the 5 seconds timeframe isn’t enough.
  2. The application needs to continue the execution even when it’s suspended, for example to keep track of the user’s position (a fitness app, a turn by turn navigator, etc.)

Let’s see how to handle both scenarios.

Complete a pending operation

This scenario is managed inside the event that the App class provides to handle the suspension. In the standard definition of this class (which is declared inside the App.xaml.cs file) you’ll find the following lines of code:

private void OnSuspending(object sender, SuspendingEventArgs e) 
{ 
    var deferral = e.SuspendingOperation.GetDeferral(); 
    deferral.Complete(); 
}

By default, this code doesn’t do anything: it just asks for a deferral, which is a way to handle asynchronous operations inside the suspension event. Without using the deferral, the beginning of an asynchronous operation may cause the immediate termination of the app by the operating system, since it’s performed on a different thread than the main one.

Inside the OnSupending() method we can use the ExtendedExecutionSession class to ask for more time, so that we have the chance to complete the running operation. Here is a sample code:

private async void OnSuspending(object sender, SuspendingEventArgs e) 
{ 
    var deferral = e.SuspendingOperation.GetDeferral(); 
    var extendedSession = new ExtendedExecutionSession(); 
    extendedSession.Reason = ExtendedExecutionReason.SavingData; 
    extendedSession.Description = "Complete synchronization"; 

    ExtendedExecutionResult result = await extendedSession.RequestExtensionAsync(); 

    if (result == ExtendedExecutionResult.Allowed) 
    { 
        UploadCompleteData(); 
    } 
    else 
    { 
        UploadBasicData(); 
    } 

    deferral.Complete(); 
} 

When we create a new ExtendedExecutionSession instance, we have to define:

  1. The reason why we need that the running operation continues even after the suspension. In our scenario, we need to use the SavingData value of the ExtendedExecutionReason enumartor.
  2. A description that briefly summarize the operation we’re going to perform. It’s a simple string.

Then we can call the RequestExtensionsAsync(). As you can imagine from the name of the method, this operation doesn’t guarantee that the request will be accepted; the operating system could decide to deny it, according to the available resources. Consequently, it’s very important to check the result of the operation, which type is ExtendedExecutionResult. Only if the result is Allowed, we are authorized to execute an operation that could take more than 5 seconds to be completed; otherwise, instead, we need to apply a workaround to satisfy the 5 seconds constraint.

It’s important to remind that this approach doesn’t allow an infinite execution time: in case resources are running low, the operating system could terminate the running activity.

Keep the application running in background

The second feature provided by the ExetendedExecutionSession class offers a bit more flexibility: when the application is suspended, in fact, it will be kept alive in background: the process won’t be frozen, but it will be able to keep performing operations, handle events, etc. It’s like if the application in foreground, except that it isn’t visible to the user. It’s a feature which can be very useful for location tracking apps: for example, a fitness app could leverage this approach to track the user’s run even if the phone is locked and placed in the user’s pocket.

This is the reason why the ExtendedExecutionSession class identifies this approach by assigning the LocationTracking value to the Reason property. Moreover, this feature requires that the Location capability is declared in the manifest file. To be honest, the operating system doesn’t force you to use the location APIs to use this feature: however, it’s important to keep in mind that the user, in the Store page, will see that your application is accessing to the user’s location, even if you aren’t actually doing it. As such, think twice before choosing to go down this path.

The main difference with the previous scenario (completing a pending operation) is the position in code when the ExtendedExceutionSession class is used: if, in the code sample we’ve previously seen, we used it inside the OnSuspending() method of the App class, now instead we need to ask the permission to the operating system to run in background as soon as possible. Typically, this is done when the main page of the application is loaded, so the OnNavigatedTo() or the Loaded() events are good candidates.

Here is a code sample:

protected override async void OnNavigatedTo(NavigationEventArgs e) 
{ 
    if (e.NavigationMode == NavigationMode.New) 
    { 
        var extendedSession = new ExtendedExecutionSession(); 
        extendedSession.Reason = ExtendedExecutionReason.LocationTracking; 
        extendedSession.Description = "Location tracking"; 

        ExtendedExecutionResult result = await extendedSession.RequestExtensionAsync(); 
        if (result == ExtendedExecutionResult.Allowed) 
        { 
            Debug.WriteLine("Background execution approved"); 
        } 
        else 
        { 
            Debug.WriteLine("Background execution denied"); 
        } 
    } 
} 

The first line of code makes sure that the initialization is made only when the navigation mode is New, which means that the page is loaded for the first time: this way, we can avoid that the initialization is repeated every time that the user, from an inner page, navigates back to the main one. If we try to initialize the ExtendedExecutionSession object multiple times, in fact, we’ll get an exception.

The rest of the code is pretty much the same we’ve seen in the previous scenario, except that:

  1. We’re setting the Reason property of the ExtendedExecutionSession class to LocationTracking.
  2. Also in this case it’s useful to check the result of the RequestExtensionAsync() method, but only for logging or warning purposes. In fact, in case the app is allowed for background execution, we won’t have anything special to do: the app will simply continue to run, like if it has never been suspended. It’s important to highlight that one of the causes that may lead to a denied execution is that the Location capability is missing in the manifest file.

It’s important to highlight that, even if the application is indeed running in background, it’s not able to interact with the UI thread: if you need to show any information to the user, you need to rely on the features provided by the platform, like notifications.

The following sample code shows how to leverage notifications in a background execution scenario:

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    protected override async void OnNavigatedTo(NavigationEventArgs e)
    {
        if (e.NavigationMode == NavigationMode.New)
        {
            var extendedSession = new ExtendedExecutionSession();
            extendedSession.Reason = ExtendedExecutionReason.LocationTracking;
            extendedSession.Description = "Location tracking";

            ExtendedExecutionResult result = await extendedSession.RequestExtensionAsync();
            if (result == ExtendedExecutionResult.Allowed)
            {
                Debug.WriteLine("Background execution approved");
            }
            else
            {
                Debug.WriteLine("Background execution denied");
            }

            Geolocator locator = new Geolocator();
            locator.DesiredAccuracyInMeters = 0;
            locator.MovementThreshold = 500;
            locator.DesiredAccuracy = PositionAccuracy.High;
            locator.PositionChanged += Locator_PositionChanged;
        }
    }

    private void Locator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
    {
        string xml = [email protected]"
            <toast activationType='foreground' launch='args'>
                <visual>
                    <binding template='ToastGeneric'>
                        <text>This is a toast notification</text>
                        <text>Latitude: {args.Position.Coordinate.Point.Position.Latitude} - Longitude: {args.Position.Coordinate.Point.Position.Longitude}</text>
                    </binding>
                </visual>
            </toast>";

        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xml);

        ToastNotification notification = new ToastNotification(doc);
        ToastNotifier notifier = ToastNotificationManager.CreateToastNotifier();
        notifier.Show(notification);
    }
}

After subscribing for background execution, we initialize the Geolocator class and we subscribe to the PositionChanged event, which is triggered every time the geo localization services detects a new position. When this event happens, we prepare the payload of a toast notification with the info about the detected longitude and latitude and then we display it, using the ToastNotification and ToastNotificationManager classes. We can easily test this application using the Windows 10 Mobile emulator: just open the app and, by leveraging the Location simulator in the Additional tools, just place a pushpin in a random map location. Every time you’ll perform this operation, you’ll see a notification with the coordinate of the selected place. However, since we requested background execution, the PositionChanged event handler will be triggered even if the app is suspended. Let’s repeat the same test (placing random pushpins on the map) but, before, suspend the app: you’ll notice that the notifications will be displayed anyway, since the app is indeed still running, even if it’s not visible.

As you can see, this features allows a lot of flexibility; consequently, there are some constraints to prevent that an app could negatively affect the battery life or the performances of the devices. First, only one application at a time can leverage the background execution; if the user opens another application that uses the same feature, the already running one will be stopped and suspended. In addition, also in this case the operating system continuously monitors the available system resources: if they are running low, it will be able to kill our running app and suspend it.

Wrapping up

The new background execution feature is very simple to manage but, at the same time, very powerful and it opens up scenarios that it wasn’t possible to support in a Windows or Windows Phone 8.1 application. You can find with a sample project that shows how to use the ExtendedExecutionSession API on my GitHub repository https://github.com/qmatteoq/Windows10-Samples. Happy coding!

Posted in Universal Apps | Tagged , | Leave a comment

Xamarin Forms for Windows Phone devs – Dependency injection with MVVM Light

In the previous post we’ve seen how Xamarin Forms offers an easy way to manage dependency injection, so that you can support the different ways how some features are managed on every platform. This way, you can use a common interface in your shared project and then have three different concrete implementation of that interface, one for each platform. In the previous sample we’ve used a PopupService, which is a class that is used to display a popup to the user by taking advantage of the specific APIs offered for each platform.

In this post, we’re going to see how to combine this approach in a MVVM project created using MVVM Light.

One project, two dependency injection’s containers

When we talked about how to create a Xamarin Forms project using MVVM Light, we’ve seen that the toolkit created by Laurent Bugnion offers a dependency injection’s container called SimpleIoC. Using a dependency container in a MVVM application is very useful, because it makes much easier to switch the implementation of a class we want to use in a ViewModel. In the previous post, we’ve seen that we are able to easily achieve this goal by using a code similar to the following one:

public MainViewModel()
{
    IPopupService popupService = container.Resolve<IPopupService>();
    popupService.ShowPopup("Sample title", "Sample message");
}

However, this code still requires you to go in each class and manually get a reference to the concrete implementation by using the container (in this sample, we’re using Unity as dependency injection library, so we use the Resolve<T>() method of the UnityContainer class.

Thanks to dependency injection, there’s a smarter way to do this: by registering both the ViewModel and the service in the container, like in the following sample.

public class ViewModelLocator
{
    static ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        SimpleIoc.Default.Register<IPopupService, PopupService>();
        SimpleIoc.Default.Register<MainViewModel>();
    }

    /// <summary>
    /// Gets the Main property.
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
        "CA1822:MarkMembersAsStatic",
        Justification = "This non-static member is needed for data binding purposes.")]
    public MainViewModel Main
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MainViewModel>();
        }
    }
}

As you can see, in the ViewModelLocator definition we’ve registered not only the MainViewModel (like we did in the previous post) but also the PopupService class, which is connected to the IPopupService interface. Thanks to this code, now we are able to get a reference to the PopupService class simply by adding an IPopupService paramter in the ViewModel’s constructor, like in the following sample:

public class MainViewModel : ViewModelBase
{
   private readonly IPopupService _popupService;

   public MainViewModel(IPopupService popupService)
   {
       _popupService = popupService;
   }
}

The dependency injection mechanism will take care of automatically injecting, into the IPopupService paramater, the concrete implementation (the PopupService) class we’ve registered in the container in the ViewModelLocator.

How to combine the two approaches

However, in the previous post, we’ve seen that Xamarin Forms offers another approach to manage dependency injection: by decorating the concrete implementation of the interface (in our case, the PopupService class) with an attribute, that allows us to use a single interface in our shared project and have three different implementations in each platform’s specific project. This way, we can deal with the fact that some features are in common across every platform (like displaying a popup or geo localizing the user) but they are implemented with different APIs and approaches.

How can we combine this approach with the standard one, so that we take the best of both worlds? Our goal is to have the MVVM Light container to automatically inject, in every ViewModel, the specific PopupService implementation we’ve included into every platform’s specific project. It’s easy, thanks to a feature offered basically by each dependency injection’s library, which is a method to register a specific instance of a class into the container. This way, when we need a concrete implementation of a class, the container will return us that specific instance, instead of creating a new one on the fly.

The following code shows how we can achieve our goal by combining the code we’ve seen in this post and in the previous one:

public class ViewModelLocator
{
    static ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        IPopupService popupService = DependencyService.Get<IPopupService>();
        SimpleIoc.Default.Register<IPopupService>(() => popupService);
        SimpleIoc.Default.Register<MainViewModel>();
    }

    /// <summary>
    /// Gets the Main property.
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
        "CA1822:MarkMembersAsStatic",
        Justification = "This non-static member is needed for data binding purposes.")]
    public MainViewModel Main
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MainViewModel>();
        }
    }
}

Unlike in the previous sample, where we generically registered the PopupService class for the IPopupService interface, in this case we register a specific instance, which we have retrieved using the DependencyService class offered by Xamarin Forms. This way, we make sure that the IPopupService object we get in return is the specific implementation for the platform where the app is running. Then, we proceed to register this instance in the SimpleIoc container, by passing it as parameter of the Register<T>() method.

That’s all: now, in our MainViewModel, the container will automatically inject, into the constructor’s parameter, the proper implementation for the current platform.

Wrapping up

In this post we’ve seen how to combine a standard dependency injection approach (which is useful to manage the ViewModel dependencies) with the Xamarin Forms one (which is useful to manage platform specific implementations of the same feature). You can play with a working sample by downloading the source code published on GitHub: https://github.com/qmatteoq/XamarinFormsSamples

Posted in wpdev, Xamarin | Tagged , | 2 Comments

Xamarin Forms for Windows Phone devs – Dependency injection

If you’re already worked with Windows Phone and Windows Store applications and, especially, with the MVVM pattern, you should be familiar with the dependency injection concept. In a typical application, when you need to use a class, you simply create a new instance, like in the following sample:

private void OnButtonClicked(object sender, EventArgs e)
{
    PopupService popupService = new PopupService();
    popupService.ShowPopup("Sample title", "Sample message");
}

This way, objects are created at compile time. However, when you work with the MVVM pattern, this approach has a downside. Let’s say that you’re using the PopupService in multiple classes (like ViewModels) and, suddenly, you need to change his implementation with a new one. With the previous approach, you are forced to go in each class where you use the PopupService and change the implementation with the new one.

With the dependency injection approach, instead, objects are registered inside a container, which is a special class that takes care of dispatching the objects when they’re required. Typically, with this approach, every class is described by an interface. For example, the PopupService class can be described with an interface called IPopupService, like in the following sample:

public interface IPopupService
{
    void ShowPopup(string title, string message);
}

Then, when the application starts, we specify for each interface which is the concrete implementation we want to use in the application, like in the following code (keep in mind that it’s just a sample, there are multiple libraries to implement dependency injection, each of them with its APIs and methods):

public App() 
{
    IUnityContainer container = new UnityContainer();
    container.RegisterType<IPopupService, PopupService>();
}

In the end, whenever a class needs to use a PopupService object, instead of simply creating a new instance, it asks to the container to return the registered one, like in the following sample:

private void OnButtonClicked(object sender, EventArgs e)
{
    IPopupService popupService = container.Resolve<IPopupService>();
    popupService.ShowPopup("Sample title", "Sample message");
}

The advantage of this approach should be clear: whenever we need to change the implementation of the IPopupService interface, it’s enough to change the concrete implementation of the interface that is registered in the container, like:

public App() 
{
    IUnityContainer container = new UnityContainer();
    container.RegisterType<IPopupService, FakePopupService>();
}

Automatically, all the classes that are using the PopupService class will immediately start to use the new implementation, called FakePopupService, simply by changing one line of code.

Dependency injection and Xamarin Forms

Dependency injection becomes very useful when you work with Xamarin Forms: the purpose of this technology is to allow developers to share as much code as possible between the three different mobile platforms (iOS, Android and Windows Phone). The Xamarin technology was created with this purpose in mind, however Xamarin Forms takes this approach to the next level, by allowing developers to share not just business logic, but also the user interface. Xamarin Forms, in fact, uses a XAML based approach: the user interface is defined using XML, where each control is identified by a specific XML tag. The biggest difference with the standard XAML (which is supported only by Microsoft technologies, like Windows Phone or WPF) is that the controls are automatically translated into the native platform controls. This way, unlike with cross platform applications based on web technologies (which offer the same UI on all the platforms), we’ll be able to keep the UI consistent with the guidelines and the user interface of the platform.

However, there are some scenarios which simply don’t fit the shared code approach. We can’t forget, in fact, that Xamarin, unlike web technologies, doesn’t provide a way to create the application just once and run it everywhere: one of the biggest pros of Xamarin, in fact, is that it allows developers to make use of every platform specific feature, unlike web applications that typically support only the features that are in common between every platform. Consequently, you still need to learn how Android and iOS development work if you want to create a real application. However, thanks to Xamarin, you won’t have to learn also a new language in the process: Xamarin, in fact, offers a way to use the native APIs with the familiar C# syntax.

The same applies for Xamarin Forms: it offers a way to share not just business logic but also user interface code but, in the end, we still need to deal with the specific platform features and implementations. Let’s say, for example, that we want to add the PopupService class we’ve previously seen in our Xamarin Forms project, which offers a ShowPopup() method that displays an alert to the user. Each platform has a different way to display a popup message: for example, in Windows Phone you use the MessageBox class; on Android, you have the AlertDialog class; on iOS, instead, you use the UIAlertView class. However, we would love to have a way to use the ShowPopup() method in our shared page and, automatically, see it rendered on each platform with its specific code.

Thanks to the dependency injection approach, we can: in the shared page we’re going to get a reference to the IPopupService class and to use the ShowPopup() method. At runtime, the dependency container will inject into the IPopupService object the specific implementation for the platform. However, compared to a regular dependency injection approach (like the one we’ve previously seen), there are some differences when we need to use it in Xamarin Forms.

Please note: the sample we’re going to see has been created just for demonstration purposes. Xamarin Forms, in fact, already offers a way to display popups to the user in a shared page, without having to deal with the different implementations for each platform.

One interface, multiple implementations

The first step is to create a common interface in the shared project, since it will be unique for each platform:

public interface IPopupService
{
    void ShowPopup(string title, string message);
}

Then we need a concrete implementation of this interface, one for each platform: we’re going to create in every specific platform project this time. For example, here is how it looks like the implementation in the Windows Phone project:

public class PopupService: IPopupService
{
    public void ShowPopup(string title, string message)
    {
        MessageBox.Show(message, title, MessageBoxButton.OK);
    }
}

Here is, instead, how it looks like in the Android project:

public class PopupService: IPopupService
{
    public void ShowPopup(string title, string message)
    {
        AlertDialog.Builder alert = new AlertDialog.Builder(Forms.Context);
        alert.SetTitle(title)
            .SetMessage(message)
            .SetPositiveButton("Ok", (sender, args) =>
            {
                Debug.WriteLine("Ok clicked"); 
            })
            .Show();
    }
}

The next step is to understand how to use the proper implementation for each platform. In our shared code, we’re going to simply use the interface, like in the following sample:

private void OnButtonClicked(object sender, EventArgs e)
{
    IPopupService popupService = new PopupService();
    popupService.ShowPopup("Sample title", "Sample message");
}

However, this code won’t simply work: we don’t have a single implementation of the PopupService class, but three different implementations, each of them with its namespace. Also the previous dependency injection approach we’ve seen doesn’t solve our problem: when we register the implementation in the container, we still need to specify which is the concrete class to use and, in our scenario, we have three of them.

Luckily, Xamarin Forms offers a smart approach to solve this situation: instead of manually registering the implementations into a container, we decorated the classes with an attribute. At runtime, automatically, Xamarin Forms will detect which is the interface connected to the implementation and will return to the application the proper object. To make it working, it’s enough to add the following attribute each concrete implementation of the class:

using System.Windows;
using DependencySample.Services;
using DependencySample.WinPhone.Services;


[assembly: Xamarin.Forms.Dependency(typeof(PopupService))]
namespace DependencySample.WinPhone.Services
{
    public class PopupService: IPopupService
    {
        public void ShowPopup(string title, string message)
        {
            MessageBox.Show(message, title, MessageBoxButton.OK);
        }
    }
}

The only variable part of the attribute is the parameter of the Dependency class: we need to specify the type of the current class (in our sample, it’s PopupService). Then, in our shared project, when we need to use the PopupService, we’re going to retrieve it using a Xamarin Forms class called DependencyService, like in the following sample:

private void OnButtonClicked(object sender, EventArgs e)
{
    IPopupService popupService = DependencyService.Get<IPopupService>();
    popupService.ShowPopup("Sample title", "Sample message");
}

We use the Get<T> method, where T is the interface of the class we want to use. Automatically, Xamarin Forms will analyze the registered DLLs in the project and will return the concrete implementation that is available in the platform’s specific project.

Wrapping up

In this post we’ve seen how to use the native dependency container that Xamarin Forms offers to developers. In the next post, we’ll see how to combine it with a traditional dependency injection approach, which comes useful when you’re developing a Xamarin Forms app using MVVM. You can download the sample project used in this post on GitHub: https://github.com/qmatteoq/XamarinFormsSamples

Posted in Xamarin | Tagged , | 4 Comments

Xamarin Forms for Windows Phone devs – Using the MVVM pattern

We’ve already talked many times about the MVVM pattern on this blog and how to implement it in Windows Phone 8 apps using Caliburn Micro or in Universal Windows apps with Caliburn Micro and Prism. The Model-View-ViewModel pattern is very useful in XAML based projects, because the separation between logic and user interface gives many advantages in testability and maintainability. However, when we’re dealing with projects that target multiple platforms with a shared code base (like with Universal Windows apps), using the MVVM pattern is, more or less, a basic requirement: thanks to the separation between logic and user interface, it becomes easier to share a good amount of code with the different projects.

Xamarin Forms makes no exceptions: applying the MVVM pattern is the best way to create a common codebase that can be shared among the iOS, Android and Windows Phone projects. In this post, we’ll see how to create a simple project using one of the most popular toolkits out there: MVVM Light.

Why MVVM Light?

MVVM Light is, for sure, the most simple and flexible MVVM toolkit available right now. It’s main advantage is simplicity: since it’s implementation is very basic, it can be easily ported from one platform to another. As you’re going to see in this post, if you have already worked with MVVM Light on other platforms, you’ll find yourself at home: except for some minor difference, the approach is exactly the same you would use in Windows Phone, Windows Store or WPF.

However, the MVVM Light simplicity is also its weak point: compared to frameworks like Caliburn Micro or Prism, it misses all the infrastructure that is often required when you have to deal with platform specific features, like navigation, application lifecycle, etc. Consequently, as we’re going to see in the next posts, you may have the need to extend MVVM Light, in order to solve platform specific scenarios. In the next post I will show you the implementation I did to solve these problem: for now, let’s just focus on implementing a basic Xamarin Forms project with MVVM Light. This knowledge, in fact, it’s important to understand the next posts I’m going to publish.

Creating the first MVVM project

The first step is the same we’ve seen in a previous post: creating a new Xamarin.Forms Blank App. After we’ve checked that we’re using the latest Xamarin Forms version, we need to install also MVVM Light in the shared project: you’ll need to install the specific version for PCL libraries, which is http://www.nuget.org/packages/Portable.MvvmLightLibs/

Now you’re ready to set up the infrastructure to create the application: let’s start by adding our first View and our first ViewModel. It’s not required, but to better design the application I prefer to create a folder for the views (called Views) and a folder for the ViewModels (called ViewModels). Then add a new Xamarin Forms page into the Views folder (called, for example, MainView.xaml) and a new simple class into the ViewModels folder (called, for example, MainViewModel.cs).

The ViewModelLocator

One of the basic requirements in a MVVM application is to find a way to connect a View to its ViewModel: we could simply create a new instance of the ViewModel and assign it as data context of the page, but this way we won’t be able to use techniques like dependency injection to resolve ViewModels and the required services at runtime (we’ll talk again about this approach in the next post). The typical approach when you work with MVVM Light is to create a class called ViewModelLocator, which takes care of passing to every View the proper ViewModel. Here is how the ViewModelLocator class looks like in a Xamarin Forms project:

public class ViewModelLocator
{
    static ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        SimpleIoc.Default.Register<MainViewModel>();
    }

    /// <summary>
    /// Gets the Main property.
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
        "CA1822:MarkMembersAsStatic",
        Justification = "This non-static member is needed for data binding purposes.")]
    public MainViewModel Main
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MainViewModel>();
        }
    }
}

When the class is created, we register the default dependency injection provider we want to use: in this case, we use the native one offered by MVVM Light, called SimpleIoc. Then, we register in the container, by using the Register<T>() method, all the ViewModels and services we want to use. In this sample, we won’t use any service: we’ll see in the next post how to manage them; so we just register our MainViewModel in the container. The next step is to create a property that will be used by the View to request the proper ViewModel instance: we use again the dependency injection container, in this case to get a registered class, by using the GetInstance<T>() method (where T is the object’s type we need).

Now we can use the ViewModelLocator to assing a ViewModel to its View: in our case, the MainView should be connected to the MainViewModel. In a Windows Phone app, this goal is typically achieved by declaring the ViewModelLocator as a global resource in the App class and then, in the XAML, assigning the proper property (in this case, Main) to the DataContext property of the page. This way, the ViewModel will be assigned as DataContext of the entire page and every nested control will be able to access to the commands and properties that are exposed by the ViewModel.

However, this approach doesn’t work in Xamarin Forms, since we don’t have the concept of global resources: we don’t have an App.xaml file, where to declare resources that are shared across every page of the application. The easiest way to solve this problem is to declare the ViewModelLocator as a static property of the App class in the Xamarin Forms shared project, like in the following sample:

public class App: Application
{
    public App()
    {
        this.MainPage = new MainView();
    }

    private static ViewModelLocator _locator;

    public static ViewModelLocator Locator
    {
        get
        {
            return _locator ?? (_locator = new ViewModelLocator());
        }
    }
}

This way, you’ll be able to connect the ViewModel to the View by using this static property in the code behind file of the page (in our case, the file MainView.xaml.cs):

public partial class MainView
{
    public MainView()
    {
        InitializeComponent();
        this.BindingContext = App.Locator.Main;
    }
}

You can notice one of the most important differences between the XAML in Windows Phone and the XAML in Xamarin Forms: the DataContext property is called BindingContext. However, its purpose is exactly the same: define the context of a control.

Define the ViewModel

Creating a ViewModel it’s easy if you’ve already worked with MVVM Light, since the basic concepts are exactly the same. Let’s say that we want to create a simple applications where the user can insert his name: by pressing a button, the page will display a message to say hello to the user. Here is how the ViewModel to manage this scenario looks like:

public class MainViewModel: ViewModelBase
{
    private string _name;

    public string Name
    {
        get { return _name; }
        set
        {
            Set(ref _name, value);
            ShowMessageCommand.RaiseCanExecuteChanged();
        }
    }

    private string _message;

    public string Message
    {
        get { return _message;}
        set { Set(ref _message, value); }
    }

    private RelayCommand _showMessageCommand;

    public RelayCommand ShowMessageCommand
    {
        get
        {
            if (_showMessageCommand == null)
            {
                _showMessageCommand = new RelayCommand(() =>
                {
                    Message = string.Format("Hello {0}", Name);
                }, () => !string.IsNullOrEmpty(Name));
            }

            return _showMessageCommand;
        }
    }
}

You can see, in action, all the standard features of a ViewModel created using MVVM Light as a toolkit:

  • The ViewModel inherits from the ViewModelBase class, which gives you some helpers to properly support the INotifyPropertyChanged interface that is required to notify the controls in the View when the properties that are connected through binding are changed.
  • Every property isn’t defined with the standard get – set approach but, when the value of the property changes (in the set method), we call the Set() method offered by MVVM Light which, other than just assigning the value to the property, takes care of dispatching the notification to the controls in the View.
  • When you work with the MVVM pattern, you can’t react to user’s actions using event handlers, since they have a strict dependency with code behind: you can’t declare an event handler inside another class. The solution is to use commands, which are a way to express actions with a property, that can be connected to the View using binding. MVVM Light offers a class that makes this scenario easier to implement, called RelayCommand. When you create a RelayCommand object, you need to set: 1) the action to perform (in our case, we define the message to display to the user) 2) optionally, the condition that needs to be satisfied for the command to be activated (in our case, the user will be able to invoke the command only if the property called Name isn’t empty). If the condition isn’t met, the control be automatically disabled. In our sample, if the user didn’t insert his name in the box, the button will be disabled.
  • When the value of the Name property changes, we also call the RaiseCanExecuteChanged() method offered by the RelayCommand we’ve just defined: this way, every time the Name property changes, we tell to the command to evaluate its status, since it could be changed.

The View

The following code, instead, show the Xamarin Forms XAML page that is connected to the ViewModel we’ve previously seen:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                       x:Class="MvvmLight_Sample.Views.MainView">
  <StackLayout Padding="12, 0, 12, 0">
    <Label Text="Insert your name:" />
    <Entry Text="{Binding Path=Name, Mode=TwoWay}" />
    <Button Command="{Binding Path=ShowMessageCommand}" Text="Show message" />
    <Label Text="{Binding Path=Message}" FontSize="30" />
  </StackLayout>
</ContentPage>

It’s a simple form, made by a text area where the user can insert his name and a button that, when it’s pressed, displays the message using a label. You can notice some difference with the standard XAML available in Windows Phone:

  • The StackPanel control, which is able to display the nested controls one below the other, is called StackLayout.
  • To define the distance of the control from the screen’s border, we use the Padding property instead of the Margin one.
  • The TextBlock control, used to display a text to the user, is called Label.
  • The TextBox control, used to receive the input from the user, is called Entry.
  • The content of the button (in this case, a text) is set using the Text property, while in the standard XAML is called Content and it accepts also a more complex XAML layout.

Except for these differences in the XAML definition, we’re using standard binding to connect the controls with the properties defined in the ViewModel:

  • The Entry control has a property called Text, which contains the name inserted by the user: we connect it to the Name property of the ViewModel, using the two-way binding.
  • The Button control has a property called Command, which is connected to the ShowMessageCommand we’ve defined in the ViewModel. This way, the button will be enabled only if the Name property isn’t empty; if it’s enable, by pressing it we’ll display the hello message to the user.
  • The hello message is stored into the Message property of the ViewModel, which is connected using binding to the last Label control in the page.

Wrapping up

In this post we’ve seen the basic concepts of using MVVM Light in a Xamarin Forms: except for some differences (like the ViewModelLocator usage), the approach should be very familiar to any Windows Phone developer that has already worked with the MVVM pattern and the MVVM Light toolkit. In the next posts we’ll take a look at how the dependency injection approach works in Xamarin Forms and how we can leverage it in a MVVM Light project. As usual, you can find the sample code used in this post on GitHub at https://github.com/qmatteoq/XamarinFormsSamples

Posted in wpdev, Xamarin | Tagged , | 2 Comments

Xamarin Forms for Windows Phone devs – Navigation and application lifecycle

One of the core concepts when you create a mobile application is navigation: it’s unlikely that an app is made by just one page, so you need to provide a way to the user to move from one page to the other. We’ve already seen, in the previous post, that the base navigation infrastructure for Xamarin Forms is provided by the NavigationPage class: by encapsulating a basic ContentPage page into a NavigationPage, we’ll be able to navigate from one page to another using the Navigation property, regardless of the platform where the application is running.

Navigate to another page

We’ve already seen that, to proper support navigation, we need to encapsulate our page into a NavigationPage. From a Windows Phone developer point of view, this operation is completely transparent to the user: a standard ContentPage and a ContentPage encapsulated into a NavigationPage will look exactly the same, since Windows Phone doesn’t provide a visual way to navigate through the different pages of the applications. The navigation is managed by the Back key, which is a physical button. In Android and iOS, instead, we can notice immediately if we’re using a NavigationPage or not: in the first case, in fact, the application will display an header with the name of the page and an arrow to go back to the previous page, if existing. The following image shows the same ContentPage on Android: the first one is directly displayed, the second one, instead, is embedded into a NavigationPage first. This is an important difference to understand if you’re coming to the Windows Phone world.

navigation

 

In the previous post we’ve seen the basic way to navigate from one page to the other: by using the PushAsync() method of the Navigation property, which requires as parameter the new page where we want to redirect the user.

private async void OnNavigateClicked(object sender, EventArgs e)
{
    await Navigation.PushAsync(new DetailView());
}

This code is the equivalent of calling the Navigate() method of the Frame class in a Windows Store app or the NavigationService class in a Silverlight app.

This sample assumes that our project has a page called DetailView: by passing a new instance to the PushAsync() method, we’ll redirect the user to this page. Again, in Windows Phone you’ll just be redirected to a new page and, to go back, you’ll just have to use the Back button; on Android and iOS, instead, the header will change and it will display, other than the page title, a virtual back button to redirect the user to the previous page. The following image will help you to understand the difference:

detail

In case you want to provide in your page an additional button to redirect the user to previous page, you can use the PopAsync() method of the Navigation class, like in the following sample:

private async void OnNavigateBackClicked(object sender, EventArgs e)
{
    await Navigation.PopAsync();
}

The previous code is the equivalent of the GoBack() method exposed by the Frame class in a Windows Store app or the NavigationService class in a Silverlight app.

Displaying a modal view

Android and iOS has the concept of “modal view”, which is a full screen page that is displayed on top of navigation stack. The difference with a standard navigation is that the navigation bar will be hidden and the page will use the whole screen: the only way to go back to the previous page is by using the Back button (in Android) or by adding a dedicated button in the page, that will invoke a specific method offered by the Navigation class. To display a page in modal view, you’ll have to use the PushModalAsync() method, like in the following sample:

private async void OnModalViewClicked(object sender, EventArgs e)
{
    await Navigation.PushModalAsync(new DetailView());
}

The following image shows the difference between a navigation to the DetailView page using the PushAsync() method (on the left) and the PushModalAsync() method (on the right): as you can see, the right page doesn’t have the navigation bar at the top.

modal

On Windows Phone, the PushModalAsync() method and the PushAsync() one has the same effect: since Windows Phone doesn’t have the concept of modal view, the PushModalAsync() method will simply redirect the user to the new page, allowing him to go back to the previous one simply by pressing the Back button. If you want to manually dismiss a modal view and redirect the user to the previous page, you can use the PopModalAsync() method:

private async void OnBackClicked(object sender, EventArgs e)
{
    await Navigation.PopModalAsync();
}

Combining different page’s types

In the previous post we’ve seen that Xamarin Forms offers different types of pages, like TabbedPage or CarouselPage, which were set directly as starting page of our application by assigning them to the MainPage property of the App class. However, we can also combine different page types, to create more complex navigation patterns. For example, we could have a NavigationPage that redirects the user to a TabbedPage, like in the following example:

private async void OnTabbedPageClicked(object sender, EventArgs e)
{
    TabbedPage tabbedPage = new TabbedPage();
    tabbedPage.Children.Add(new DetailView());
    tabbedPage.Children.Add(new AnotherView());
    await Navigation.PushModalAsync(tabbedPage);
}

With this code, the user will be redirected from the current page to another page that will display two different sections: one connected to the DetailView page, the other one to the AnotherView page. Vice versa, we could have a TabbedPage that contains, as children, a NavigationPage, so that we can perform additional navigations from that page:

public class App : Application
{
    public App()
    {
        TabbedPage tabbedPage = new TabbedPage();
        NavigationPage navigationPage = new NavigationPage(new MainView());
        tabbedPage.Children.Add(navigationPage);
        tabbedPage.Children.Add(new AnotherView());

        this.MainPage = tabbedPage;
    }
}

This way, the first section of the tab control (which is a MainView page) will allow the user to navigate to another page of the application (like a detail page). The following image shows a NavigationPage displayed inside a tab:

image

Again, you won’t notice instead any difference in the Windows Phone application: you will just see a Pivot control with two items, one for the MainView and one for the AnotherView pages.

image

The only thing to keep in mind, in this scenario, is that the TabbedPage takes, as label for the tab, the title of the page: in this case, since we’re not directly setting as tab content the ContentPage, but we have wrapped it into a NavigationPage, we have also to set its Title property, otherwise the tab label will be empty. This is the proper code:

public class App : Application
{
    public App()
    {
        TabbedPage tabbedPage = new TabbedPage();
        NavigationPage navigationPage = new NavigationPage(new MainView()) { Title = "Main page"};
        tabbedPage.Children.Add(navigationPage);
        tabbedPage.Children.Add(new AnotherView());

        this.MainPage = tabbedPage;
    }
}

Page navigation

One common requirement in a mobile application is to detect is moving towards the current page or he’s navigating away to go to another page. This approach is very well known to Windows Phone developers: Windows Store apps, in fact, offer the OnNavigatedTo() and OnNavigatedFrom() events, which are often used to load data or to unsubscribe to event handlers. The OnNavigatedTo() event is especially useful to load the data to display in the current page: since it’s an event handler, we can use it also to invoke asynchronous method with the async / await pattern (which, instead, is not possible in the page’s constructor).

These two events are mapped in Xamarin Forms with the OnAppearing() method (that is invoked when the page is being displayed) and the OnDisappearing() method (that is invoked when the user is moving away from the current page):

public partial class MainView
{
    public MainView()
    {
        InitializeComponent();
    }

    protected override void OnAppearing()
    {
        Debug.WriteLine("Page is appearing");
    }

    protected override void OnDisappearing()
    {
        Debug.WriteLine("Page is disappearing");
    }
}

The application lifecycle

If you’re a Windows Phone developer, you should be familiar with the concept of application’s lifecycle. To satisfy the typical requirement of a mobile environment (performance, battery consumption, etc.) all the mobile platform applies constraints to the operations that an application can perform in background. On all the platforms, typically, when an application isn’t in foreground anymore is suspended and it doesn’t have the chance to perform operation: this scenario is managed using other approaches, like background tasks in Windows Phone.

Xamarin Forms has added three methods in the shared App class to properly manage the application’s lifecycle, in case you need to perform additional operations when the app is launched, suspended or resumed. The following sample shows how to declare and use these events:

public class App : Application
{

   protected override void OnStart()
   {
       Debug.WriteLine("Application started");
   }

   protected override void OnSleep()
   {
       Debug.WriteLine("Application suspended");
   }

   protected override void OnResume()
   {
       Debug.WriteLine("Application resumed");
   }
}

If you are a Windows Phone developer, these events should be familiar to you:

  • OnStart() is called when the application is launched from scratch.
  • OnSleep() is called when the application is suspended.
  • OnResume() is called when the application is resumed. It’s important to highlight that this method is invoked only when a previous instance of the app was kept in memory and it’s restored: for example, on Windows Phone, in case of tombstoning (so the process was terminated by the operating system due to low resources) you’ll trigger the OnStart() method at startup and not the OnResume() one.

Wrapping

In this posts we’ve seen the basic concept of navigation and application’s lifecycle management and how they compare to the Windows Phone approach. In the next posts, we’ll start to see how to create a real application using the MVVM pattern. As usual, you can find the samples used in this post on GitHub: https://github.com/qmatteoq/XamarinFormsSamples

Posted in wpdev, Xamarin | Tagged , | 4 Comments