MVP for another year!

For me the first day of the year is always a special day: not only because it’s a day full of hope for the things that are going to come during the year, but also because it’s the day in which, since 2011, my MVP status expires. If you’re not familiar with the MVP, it’s an award gifted by Microsoft to the community leaders for their passion and enthusiasm in sharing their knowledge about Microsoft technologies (in my case, about Windows Phone development). It’s not a “one time” award: you have to earn it every year and to prove that you still deserve it. For me, this time of the year is 1st January: and I’m really happy to say that Microsoft has confirmed his trust in me and renewed my award also for 2014!

2013 has been a crazy year for me as an MVP: 2 summits, the release of my first book, the Windows Phone Week organization, the Italian webinar series with Nokia and much much more. There are so many people to thank for this great year! The first one is, for sure, my wife Angela, that keeps supporting me, even when my activities steal some of the time that we can spend together. Then, in random order:

  • Lorenzo Barbieri, which is not only a friend but he’s also the best supporter (together with the DPE department) of the Windows Phone activities that we organize with the community.
  • Daniele Pagani, Luca De Bernardi and Frangino Lucarini, which are part of the Italian Nokia team that are doing an amazing job in supporting the Italian Windows Phone developers and our activities as Nokia Champions.
  • Desiree Lockwood, the referral for our activities as Windows Phone Development MVPs. She’s an amazing person and she’s doing a terrific job. Without her, the Windows Phone Week (and many other activities) would have been just a crazy idea.
  • The Windows Phone Development’s MVP family (with a special mention to Joost Van Schaik): they’re the living proof that being part of the MVP family doesn’t mean just connecting with great professionals, but also that you can find and meet great friends, even if they live far away from you.
  • Ugo Lattanzi: if today I have the pleasure to be part of the MVP family it’s totally his fault Smile He’s the one that, 5 years ago, made me discover the community world and conviced me to open a blog and to do my first speech about Windows Phone. Everything started right there Smile
  • Roberto Freato and the DotNetLombardia crew, which accepted me as part of the community and involved (and keep involving me) in all their activities.
  • Funambol and my team: I’ve joined the company more than 1 year ago and it has been one of the best things that happened in my life. I met many special people and friends and I love the way the company keeps supporting my community activites. I’m really proud to be part of it!

But, of course, my biggest thank goes to all the developers and communities out there, which keeps supporting and believing in me. I’m looking forward to keep working with you in 2014!

Posted in Windows Phone | Tagged | Leave a comment

Say hello to WP Dev Fusion!

For sure one of the best 2013 moments for me was the Windows Phone Week organization: born as a crazy idea from three friends, it quickly turned out into an international initiative that brought more than 20 events all around the world. Seeing the enthusiasm and the passion of all the Windows Phone developers out there was really great and insipiring.  All of us instantly understood that this couldn’t be a “one time experience”: we had to find a way to keep supporting all the Windows Phone developers to find great content and to meet each other and, at the same time, to grow and to learn from our mistakes.

So.. say hello to WP Dev Fusion! My MVP friend Peter Nowak, from Germany, had a great idea: Windows Phone Week was great, but what about all the people that weren’t able to join a local event? Why we don’t find a way to support and get in touch with everyone? So WP Dev Fusion was born, as the natural successor of the Windows Phone Week.

What is WP Dev Fusion? It’s a new community initiative, with the goal to continue the good work made with the Windows Phone Week and to expand it, so that we can reach developers from all around the world. WP Dev Fusion will continue to have a traditional offline soul: you will see, for sure, new events and initiative organized in various places all around the world with the WP Dev Fusion brand, thanks to Microsoft and Nokia support. But we will have also an online soul: other than just spreading the latest and most important news about Windows Phone development with our social channels, we’ll regularly organize virtual conferences, that can be followed online from the comfort of your home. This way, we’ll deliver the best content with the support of the best speakers directly to your home!

And which is the best way to launch a new community initiative? To organize a conference, of course! So let me introduce you to the first WP Dev Fusion virtual conference, that will be hosted on 22nd January 2013, starting from 6 PM (CET timezone): after a brief introduction, a group of Windows Phone Development MVPs will introduce you to many development topics, like maps, speech API, App Studio, etc. I’ll have the chance to speak too about local data access in Windows Phone applications. Like in a traditional conference, you’ll have the chance to ask questions and to give feedback. At the end of the day, we’ll host also a “Ask The Expert” session, so that you’ll be able to ask any question you may have about developing apps for Windows Phone.

So, what are you waiting for? Go to the official website to register and to read the complete agenda: registration is needed to understand how many people will join and to prepare the needed infrastructure. You’ll be contacted with all the needed information to get access to the conference before 22nd January.

See you online!

Posted in Windows Phone | Tagged | Leave a comment

Integrating Facebook in your Windows Phone app using the Facebook app

If you’re a Windows Phone user, you’ll probably know that Microsoft offers two Facebook applications: an official one and a beta one. The second one is simply a “test field” for all the new features that, from time to time, are added to the application by the team: after a reasonable time, the features are considered stable and are “promoted” and added also to the official application. Some months ago Microsoft has added to the beta application a really interesting feature for developers: a way to use it as a “bridge” to integrate Facebook into our applications. This feature still relies on the existing Facebook SDK for .NET (a library available on NuGet to easily integrate Facebook in our applications) but, instead of asking to devs to create their own login page in their apps, everything is made by the Facebook app. Here is the flow if you start using this new feature:

  1. Our application starts the login procedure.
  2. The Facebook app is opened: the user will have to eventually login and to confirm the permissions.
  3. The user is returned to our application but, this time, we will receive the Access Token that is needed by the Facebook SDK to perform any operation (like posting a message or getting information about the logged user).

The biggest pro of this approach is that we need to write less code and that, in most of the cases, the user will just have to grant the permissions to the app: since the user, probably, regularly uses the Facebook app, he’s already logged in, so he won’t have to insert his credentials every time. And if he doesn’t have the app? No problem: since the method is based on the protocol sharing feature that has been added in Windows Phone 8, the user will simply be asked if he wants to download the app from the Store.

Since a few days ago, this feature was available just for testing scenarios: most of the people use the official version, not the beta one. Plus, since the beta application is hidden in the Store (you can reach it just with the deep link), in case the user doesn’t have it the user will still be prompted to search for the app on the Store, but he won’t be able to find it. However, now the official application has been updated with all the latest beta improvements, including the authentication support, so there’s no reason why you shouldn’t use it!

This feature was detailed in a blog post made by the team, which I used as a “training ground” to write this post. The official post is really good, but it can be hard to understand if you aren’t an experienced Windows Phone developer, since it assumes that the reader already knows many concepts like Uri associations, the UriMapper class, etc.

So, let’s see how to do it in a more detailed way.

Publish your app

Probably you’re wondering why publishing your app, which should be the last step, is reported at the beginning of this post. To properly set up the authentication process, you’ll need to include in your application your real Application Id. The problem is that, when you create a new application with Visual Studio, a random id is generated and assigned to the app: when the app is submitted on the store, the real application id is generated and included in the manifest. The first step is to ask to the Dev Center to generate an application id for us: to do it, you just have to start the submission process and to upload the XAP file (in Step 2). Then, simply abort the process by returning in the main page of your dashboard: you’ll find your app in the In-progress submissions list. Click on it and switch to the Details section: you’ll find the App ID section already populated with the real application id. Copy it: we’re going to use it later. Important! When your app is finished and you’re ready to publish it, you’ll have to resume this pending submission and not to start a new one: otherwise, the application will get a new application id, breaking the Facebook authentication process we’re going to set up in the next steps.

Register the application on Facebook

The second step is to register the application on Facebook: every application that needs to interact with the Facebook APIs has to be registered in the Facebook developer’s portal. This way, you’ll get some information that will be important to use the Facebook SDK (like the App Id assigned by Facebook). To do this, go to https://developers.facebook.com, click on the Apps link in the upper menu and choose Create new app. To interact with the Windows Phone application there are only two fields that are required:

  • The name of the application, which has to be set in the Display Name field.
  • How the application integrates with Facebook: choose Windows App from the list and, in the Windows Phone Store ID [BETA] section, paste the Application Id you previously copied from the Dev Center (you’ll have to remove the hypens so if, for example, your id is b94ca943-21f1-4ef7-9895-b44a32dc1230, you’ll have to past b94ca94321f14ef79895b44a32dc1230 as value).

image

Register the protocol in the manifest

Protocol sharing is one of the new features introduced in Windows Phone 8 that allows an app to register a specific protocol (like foo:/), so that other apps can interact with your application by using that protocol. This technique is used to properly manage the Facebook login: the Facebook application, after the login, will call back your application using a specific Uri. This way, you’ll be able to intercept the call and to get the result of the login process. To register a protocol, you have to edit the manifest file: you’ll have to do it manually, since this scenario is not supported by the visual editor. Just right click on the manifest file (the one called WMAppManifest.xml inside the Properties folder) and choose View code: you’ll get access to the XML version of the manifest.

Under the section called Tokens you’ll have to add a new section called Extensions in the following way:

<Extensions>
  <Protocol Name="msft-b94ca94321f14ef79895b44a32dc1230" NavUriFragment="encodedLaunchUri=%s" TaskID="_default" />
</Extensions>

The only thing you’ll need to change is the value in the Name attribute, which should be msft- followed by the same application id you’ve retrieved from the Dev Center and that you’ve pasted in the Facebook Developers Center (as you can notice, also in this case you’ll have to remove the hyphens).

Start coding

Now you’re ready to write some code and to effectively start the login process. The first step is to install two libraries from NuGet, which will provide the needed APIs to interact with Facebook: the first one is the Facebook for .NET SDK (which we already mentioned), while the second one is the Facebook Client for .NET SDK (which adds a set of libraries that are specific for Windows Phone and Windows Store apps). Please note that, to find the second package in NuGet, you have to extend the search also to pre-release packages.

The second step, which is not required but it will make things easier, is to use a class developed by Microsoft as a sample called SessionStorage: it’s a simple class that acts as a wrapper of the IsolatedStorageSettings class, but that is able to encrypt the data. This way, we’re going to save in safety the access token returned by Facebook. To create this helper simply creates a new class, called it SessionStorage and paste the following code:

public class SessionStorage
{
    /// <summary>
    /// Key used to store access token in app settings
    /// </summary>
    private const string AccessTokenSettingsKeyName = "fb_access_token";

    /// <summary>
    /// Key used to store access token expiry in app settings
    /// </summary>
    private const string AccessTokenExpirySettingsKeyName = "fb_access_token_expiry";

    /// <summary>
    /// Key used to state in app settings
    /// </summary>
    private const string StateSettingsKeyName = "fb_login_state";

    /// <summary>
    /// Tries to retrieve a session
    /// </summary>
    /// <returns>
    /// A valid login response with access token and expiry, or null (including if token already expired)
    /// </returns>
    public static FacebookSession Load()
    {
        // read access token
        string accessTokenValue = LoadEncryptedSettingValue(AccessTokenSettingsKeyName);

        // read expiry
        DateTime expiryValue = DateTime.MinValue;
        string expiryTicks = LoadEncryptedSettingValue(AccessTokenExpirySettingsKeyName);
        if (!string.IsNullOrWhiteSpace(expiryTicks))
        {
            long expiryTicksValue = 0;
            if (long.TryParse(expiryTicks, out expiryTicksValue))
            {
                expiryValue = new DateTime(expiryTicksValue);
            }
        }

        // read state
        string stateValue = LoadEncryptedSettingValue(StateSettingsKeyName);

        // return true only if both values retrieved and token not stale
        if (!string.IsNullOrWhiteSpace(accessTokenValue) && expiryValue > DateTime.UtcNow)
        {
            return new FacebookSession()
            {
                AccessToken = accessTokenValue,
                Expires = expiryValue,
                State = stateValue
            };
        }
        else
        {
            return null;
        }
    }

    /// <summary>
    /// Saves an access token an access token and its expiry
    /// </summary>
    /// <param name="session">A valid login response with access token and expiry</param>
    public static void Save(FacebookSession session)
    {
        SaveEncryptedSettingValue(AccessTokenSettingsKeyName, session.AccessToken);
        SaveEncryptedSettingValue(AccessTokenExpirySettingsKeyName, session.Expires.Ticks.ToString());
        SaveEncryptedSettingValue(StateSettingsKeyName, session.State);
    }

    /// <summary>
    /// Removes saved values for access token and expiry
    /// </summary>
    public static void Remove()
    {
        RemoveEncryptedSettingValue(AccessTokenSettingsKeyName);
        RemoveEncryptedSettingValue(AccessTokenExpirySettingsKeyName);
        RemoveEncryptedSettingValue(StateSettingsKeyName);
    }

    /// <summary>
    /// Removes an encrypted setting value
    /// </summary>
    /// <param name="key">Key to remove</param>
    private static void RemoveEncryptedSettingValue(string key)
    {
        if (IsolatedStorageSettings.ApplicationSettings.Contains(key))
        {
            IsolatedStorageSettings.ApplicationSettings.Remove(key);
            IsolatedStorageSettings.ApplicationSettings.Save();
        }
    }

    /// <summary>
    /// Loads an encrypted setting value for a given key
    /// </summary>
    /// <param name="key">The key to load</param>
    /// <returns>
    /// The value of the key
    /// </returns>
    /// <exception cref="KeyNotFoundException">The given key was not found</exception>
    private static string LoadEncryptedSettingValue(string key)
    {
        string value = null;
        if (IsolatedStorageSettings.ApplicationSettings.Contains(key))
        {
            var protectedBytes = IsolatedStorageSettings.ApplicationSettings[key] as byte[];
            if (protectedBytes != null)
            {
                byte[] valueBytes = ProtectedData.Unprotect(protectedBytes, null);
                value = Encoding.UTF8.GetString(valueBytes, 0, valueBytes.Length);
            }
        }

        return value;
    }

    /// <summary>
    /// Saves a setting value against a given key, encrypted
    /// </summary>
    /// <param name="key">The key to save against</param>
    /// <param name="value">The value to save against</param>
    /// <exception cref="System.ArgumentOutOfRangeException">The key or value provided is unexpected</exception>
    private static void SaveEncryptedSettingValue(string key, string value)
    {
        if (!string.IsNullOrWhiteSpace(key) && !string.IsNullOrWhiteSpace(value))
        {
            byte[] valueBytes = Encoding.UTF8.GetBytes(value);

            // Encrypt the value by using the Protect() method.
            byte[] protectedBytes = ProtectedData.Protect(valueBytes, null);
            if (IsolatedStorageSettings.ApplicationSettings.Contains(key))
            {
                IsolatedStorageSettings.ApplicationSettings[key] = protectedBytes;
            }
            else
            {
                IsolatedStorageSettings.ApplicationSettings.Add(key, protectedBytes);
            }

            IsolatedStorageSettings.ApplicationSettings.Save();
        }
        else
        {
            throw new ArgumentOutOfRangeException();
        }
    }
}

Now it’s time to start the real login procedure, which is done using the FacebookSessionClient class: to create a new instance you’ll have to pass as parameter the Facebook application id, which you can find on the Facebook Developers portal page (see the following screenshot).

image

Here is a full login sample:

private void OnLoginClicked(object sender, GestureEventArgs e)
{
    FacebookSessionClient fb = new FacebookSessionClient("563659977051507");
    fb.LoginWithApp("basic_info,publish_actions,read_stream", "custom_state_string");
}

To effectively perform the login you have to use the LoginWithApp method, which requires two parameters:

  • The first one is the list of permissions you want to use. You can find all the available ones here; the previous code is used to grant access to the user profile, to his timeline and to allow the app to post on behalf of the user.
  • The second parameter is a custom string that is returned to the application once the login procedure is completed: we’re going to use it to implement our own logic when the user is redirected back to our application (for example, to perform an action or to redirect the user to a specific page).

As we’ve previously described, this new login method is based on the Windows Phone 8 protocol sharing feature: this means that, when the Facebook app has completed the login, it calls back our application with a special Uri. We need to intercept it and to retrieve the query string parameters, that are needed to understand if the operation completed with success or not. The best way to achieve this task is to use a UriMapper class: you should be already familiar with this approach if you’ve already worked with scenarios like protocol sharing or speech APIs. Basically, this class acts as a middle man between every navigation: every time the user moves from a page to another, this class intercepts the navigation and he’s able to analyze the calling Uri and, eventually, to change it or to redirect the user to another page. This behavior is extended also to navigation from and towards the Start screen or another application: when the Facebook application has completed the login, the UriMapper will intercept it and will be able to extract the parameters we need.

To create the UriMapper, simply just add a new empty class to your project: you’ll have to inherit from the UriMapperBase class, which will force you to implement the MapUri() method. Here is the full code:

public class FacebookUriMapper: UriMapperBase
{
    private bool facebookLoginHandled;

    public override Uri MapUri(Uri uri)
    {
        if (AppAuthenticationHelper.IsFacebookLoginResponse(uri))
        {
            FacebookSession session = new FacebookSession();
            try
            {
                session.ParseQueryString(HttpUtility.UrlDecode(uri.ToString()));

                // Handle success case
                // do something with the custom state parameter
                if (session.State != "custom_state_string")
                {
                    MessageBox.Show("Unexpected state: " + session.State);
                }
                else
                {
                    // save the token and continue (token is retrieved and used when the app
                    // is launched)
                    SessionStorage.Save(session);
                }
            }
            catch (Facebook.FacebookOAuthException exc)
            {
                if (!this.facebookLoginHandled)
                {
                    // Handle error case
                    MessageBox.Show("Not signed in: " + exc.Message);
                    this.facebookLoginHandled = true;
                }
            }
            return new Uri("/MainPage.xaml", UriKind.Relative);
        }
        // by default, navigate to the requested uri
        return uri;
    }
}

This code checks if the Uri used to open the app the one used by the Facebook app: in this case, we’re going to create a Facebook session by using the information we’ve got in return in the Uri. If it’s a valid Facebook session (do you remember the custom string we’ve passed to the LoginWithApp() method?), we use the SessionStorage class we’ve created before to store the session data.

The last step to enable the UriMapper is to register in the in the application’s frame: open the App.xaml.cs file and look for a method called InitializePhoneApplication() (which, by default, is hidden in a collapsed region called Phone application initialization). Right after the RootFrame object has been initalized simply create a new instance of your UriMapper class and assign it to the UriMapper property, like in the following sample:

RootFrame = new PhoneApplicationFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;
RootFrame.UriMapper = new FacebookUriMapper();

Interacting with Facebook: getting data

Now you have a valid Facebook access token, which you can use to perform one of the operations offered by the FacebookClient class provided by the Facebook C# SDK. This class acts as a wrapper of the Facebook REST APIs and offers many methods to interact with Facebook by wrapping the standard HTTP commands (for example, GET to retrieve data or POST to submit changes).

The following sample shows how to retrieve the logged user’s name:

private async void OnShowNameClicked(object sender, GestureEventArgs e)
{
    FacebookSession session = SessionStorage.Load();
    FacebookClient client = new FacebookClient(session.AccessToken);

    dynamic result = await client.GetTaskAsync("me");
    string name = result.name;
    MessageBox.Show(name);
}

The first step is to load the session we’ve previously stored after the login process by using the Load() method of the SessionStorage class. Now that we have a FacebookSession object we can use it to get the information we need: specifically, we need the value of the AccessToken property, which has to be passed as parameter when you create a new instance of the FacebookClient class.

Since, to retrieve information from Facebook, we have to issue a GET operation, we need to use the GetTaskAsync() asynchronous method, which is based on the Facebook’s Open Graph APIs. As parameter it needs the Open Graph’s path: me is the path used to get information about the logged user.

The method returns a dictionary, which is a collection of data identified by a key: in this case, every key identifies one of the user’s information (for example, the key called name contains the user’s name). In the sample code you can see a different way to manage this scenario: by using the dynamic keyword, we are able to work with the value returned by the GetTaskAsync() method like if it’s a dynamic object (in a similar way when you work with dynamic languages like Javascript). This way, we are able to simply get the name of the user by asking for the value of the name property of the result. We could have used another property like surname or birthday to get other information about the user: you can see the full list here.

Integrating with Facebook: posting data

Another common scenario when you want to integrate Facebook in your application is posting messages. Here is a sample code to post a message on the user’s timeline:

private async void OnPostMessageClicked(object sender, GestureEventArgs e)
{
    FacebookSession session = SessionStorage.Load();
    FacebookClient client = new FacebookClient(session.AccessToken);

    var parameters = new Dictionary<string, object>();
    parameters.Add("message", "First test post using Facebook login");

    await client.PostTaskAsync("me/feed", parameters);
}

The first part of the code is the same we’ve seen before: by using the SessionStorage class we retrieve the access token to create a new instance of the FacebookClient class.

The biggest difference between this code and the previous one is that, in case of posting, we need to interact with the Open Graph APIs passing a parameter: we do it by creating a new set of parameters (which is a Dictionary<string, object> collection) and by adding a parameter called message. The value of the parameter is simply the text of the message we want to post.

In the end, we use the PostTaskAsync() method, since in this case we’re going to execute a POST request: other than the specifying the Open Graph APIs path (in this case, me/feed) we need to pass the input parameters we’ve just defined.

Wrapping up

There are many other operations that you can do with the Facebook C# SDK: you can find many samples here, just keep in mind that these samples are based on the old Facebook .NET SDK version, which was based on the callback approach for asynchronous method instead of the async / await one.

The biggest pro of this approach is that it saves you a lot of time working with Facebook login, which is probably the most complex scenario to implement when you have to deal with Facebook integration. In addition, it will offer a better experience to the user: since most of the time he’s already using the Facebook app, he won’t have to insert his credentials every time. The only downside, instead, is that it relies on a third party application: in case the user doesn’t have the official Facebook app (because, for example, he prefers to use another app or the mobile website) he will have to download it before using the Facebook integration in your app. This requirement may lead the user to change his mind and stop using your application.

Posted in Windows Phone | Tagged | 15 Comments

Fast App Resume and Caliburn Micro

Fast App Resume is one of the new features introduced in Windows Phone 8 that allows developers to introduce a smoother experience in their applications. The standard navigation experience is that, when a user suspends the application, he’s able to resume it only by pressing the Back button or by using the task switcher. If he launches the same application using the main tile or the icon in the application list, the suspended process is terminated and a new instance of the app is executed. The result is that, whatever the user was doing, he will have to start from scratch.

Fast App Resume introduces a more user friendly experience: the user is able to definitely quit from the application only by pressing the Back button in the main page. In every other case (including tapping the main tile or the icon in the application list) the previous instance is resumed. This way the user doesn’t have to remember that, to resume the work he was previously doing, he has to use the task switcher: regardless of the way he is going to open the app, he’ll be able to keep using the app from where he left. Anyway, Fast App Resume is a double edged sword: not always the user has the need to resume his work, but he just need to start from beginning.  Think about, for example, a Twitter client: most of the time, when the user opens the app he wants to see his timeline and not to keep reading the tweet he was looking at the last time he used the app (that could have happened many hours before). So, my suggestion is: use Fast App Resume carefully!

After this brief introduction, let’s get back to the core of the post: implementing Fast App Resume means editing the manifest and apply some changes to the navigation events of the Windows Phone’s main frame (which class is called PhoneApplicationFrame and takes care of managing all the rendering of the pages and the navigation system). From a developer’s point of view, the operation needs to be done in the App.xaml.cs class: when the PhoneApplicationFrame object is created, you have to subscribe to the Navigated and Navigating events and apply some code, that we’ll see later.

The problem when you work with Caliburn Micro is that all the application’s setup is made by the boostrapper class: initialization is removed from the App.xaml.cs class, so you don’t have a way anymore to make the needed changes. A good alternative is to use the boostrapper class, since it replaces the App one: the problem is that, by default, you don’t have a way to access to the PhoneApplicationFrame class in the bootstrapper.

But there’s a workaround Smile The boostrapper class, by default, initializes the PhoneApplicationFrame under the hood, but it offers a method that can be used to customize the process. It’s useful in case you want to override, for example, the default frame with another one (like the TransitionFrame included in the Windows Phone Toolkit that offers built-in support to transitions). The name of the method is CreatePhoneApplicationFrame and should return a PhoneApplicationFrame object (which is the basic class that every frame class inherits from). In our case, we can use it just to define a private instance of the PhoneApplicationFrame class, that we’re going to use to subscribe to the Navigated and Navigating events.

Here is the code:

public class AppBootstrapper : PhoneBootstrapperBase
 {
     private PhoneContainer container;
     private PhoneApplicationFrame rootFrame;

     public AppBootstrapper()
     {
         Start();
     }

     protected override PhoneApplicationFrame CreatePhoneApplicationFrame()
     {
         rootFrame = new PhoneApplicationFrame();
         return rootFrame;
     }
}

We’re basically doing the same things that the boostrapper does under the hood: the difference is that, this time, since we have an explicit reference to the PhoneApplicationFrame object, we can use it in our code.

What we’re going to use it for? To properly support Fast App Resume we need to intercept two navigation events: Navigated (that is triggered every time the user has navigated to another page) and Navigating (which, instead, is triggered just before the navigation is performed). It’s important to keep in mind, at this point, that navigating to another page doesn’t necessarily mean navigating from an application’s page to another page. It can be also a suspension (navigation from a page to the start screen) or a restore or launch (navigation from the start screen to a page).

The first step to continue our implementation is to change the Configure() method of the boostrapper and add two event handlers, to subscribe to the two events, like in the following sample:

protected override void Configure()
{
    container = new PhoneContainer();
    if (!Execute.InDesignMode)
        container.RegisterPhoneServices(RootFrame);

    container.PerRequest<MainPageViewModel>();

    AddCustomConventions();

    rootFrame.Navigated += rootFrame_Navigated;
    rootFrame.Navigating += rootFrame_Navigating;
}

void rootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
{
    throw new NotImplementedException();
}

void rootFrame_Navigated(object sender, NavigationEventArgs e)
{
    throw new NotImplementedException();
}

To better understand the code we’re going to write, let’s explains how Fast App Resume works from a developer point of view: usually, when you tap on the main tile, you launch a new instance of the app with, as navigation uri, the main page of the application. The same happens when Fast App Resume is enabled: the difference is that, this time, the previous instance of the app will be resumed, with the last page visited by the user already at the top of the navigation stack. The problem is that, since the main tile triggers a navigation to the main page, the user won’t see the last opened page, but the main one. Other than being an incorrect behavior, it will cause also a navigation issue: if the user presses Back on the main page, he will be redirected to the last opened page, instead of closing the app. So, the goal for the developer that correctly wants to support Fast App Resume is to detect this scenario and to cancel the navigation towards the main page: this way, the user will correctly stay on the last opened page.

To achieve this goal we’re going to use the Navigated and Navigating events we’ve previously defined.

We need to use the Navigated event to understand the navigation’s type that has been triggered: this event returns a parameter called NavigationMode, which explains which type of navigation has been issued, like Back, Forward, New, etc. One of the possible values is Reset: this is the one we’re looking for, since it’s triggered when the user has opened the application using the main tile or the icon in the application list but Fast App Resume is enabled. We need to store this information for a later use: it’s required because the Navigated event is the only one that can give us this information, but, since the navigation has already been completed at this time, we can’t cancel it. So we’re going to define a global property in the boostrapper, which type is bool, and we’re going to set it to true in case the NavigationMode property is equal to Reset. In an application that supports Fast App Resume, we’re going to get this information when app is resumed and initial navigation to the last opened page is triggered.

public class AppBootstrapper : PhoneBootstrapperBase
  {
      private PhoneContainer container;
      private PhoneApplicationFrame rootFrame;
      private bool reset;

      public AppBootstrapper()
      {
          Start();
      }

      protected override PhoneApplicationFrame CreatePhoneApplicationFrame()
      {
          rootFrame = new PhoneApplicationFrame();
          return rootFrame;
      }

      protected override void Configure()
      {
          container = new PhoneContainer();
          if (!Execute.InDesignMode)
              container.RegisterPhoneServices(RootFrame);

          container.PerRequest<MainPageViewModel>();
          container.PerRequest<Page2ViewModel>();

          AddCustomConventions();

          rootFrame.Navigated += rootFrame_Navigated;
          rootFrame.Navigating += rootFrame_Navigating;
      }

      void rootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
      {
         throw new NotImplementedException();
      }

      void rootFrame_Navigated(object sender, NavigationEventArgs e)
      {
          reset = e.NavigationMode == NavigationMode.Reset;
      }
}

Now that we have this information, we are ready to cancel the navigation to the main page in case the user opens the app from the main tile and a previous instance of the app is already available in memory. To satisfy this requirement, we’re going to use the Navigating event, that we’re going to use to intercept the navigation to the main page of the app before it’s completed. This second navigation is triggered immediately after the first one to the last opened page is completed (the one we intercepted with the Navigated event). We need to cancel this second navigation if the following conditions are satisfied:

  • Fast Application Resume is enabled.
  • The NavigationMode parameter that we got in the Navigated event is equal to Reset.
  • The Uri of the page where the user is navigating to is the main page.

Here is how these conditions are translated into code:

void rootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
{
    if (reset && e.IsCancelable && e.Uri.OriginalString == "/Views/MainPage.xaml")
    {
        e.Cancel = true;
        reset = false;
    }
}

We check the value of the boolean property we’ve defined before (called reset) and we check the navigation uri (stored in the NavigatingCancelEventArgs parameter). Of course, you’ll have to adapt your code according to the position and the name of the main page of your application: usually, it’s the same that is set in the manifest file, in the field called Navigating page. If these conditions are satisfied, we’re going to set the Cancel property of the method’s parameter to true: this way, the navigation to the main page will be canceled and the user will stay on the last visited page.

Here is the full code of the bootsrapper to properly support Fast App Resume:

public class AppBootstrapper : PhoneBootstrapperBase
{
    private PhoneContainer container;
    private PhoneApplicationFrame rootFrame;
    private bool reset;

    public AppBootstrapper()
    {
        Start();
    }

    protected override PhoneApplicationFrame CreatePhoneApplicationFrame()
    {
        rootFrame = new PhoneApplicationFrame();
        return rootFrame;
    }

    protected override void Configure()
    {
        container = new PhoneContainer();
        if (!Execute.InDesignMode)
            container.RegisterPhoneServices(RootFrame);

        container.PerRequest<MainPageViewModel>();
        container.PerRequest<Page2ViewModel>();

        AddCustomConventions();

        rootFrame.Navigated += rootFrame_Navigated;
        rootFrame.Navigating += rootFrame_Navigating;
    }

    void rootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
    {
        if (reset && e.IsCancelable && e.Uri.OriginalString == "/Views/MainPage.xaml")
        {
            e.Cancel = true;
            reset = false;
        }
    }

    void rootFrame_Navigated(object sender, NavigationEventArgs e)
    {
        reset = e.NavigationMode == NavigationMode.Reset;
    }

    protected override object GetInstance(Type service, string key)
    {
        var instance = container.GetInstance(service, key);
        if (instance != null)
            return instance;

        throw new InvalidOperationException("Could not locate any instances.");
    }

    protected override IEnumerable<object> GetAllInstances(Type service)
    {
        return container.GetAllInstances(service);
    }

    protected override void BuildUp(object instance)
    {
        container.BuildUp(instance);
    }

    private static void AddCustomConventions()
    {
        ConventionManager.AddElementConvention<Pivot>(Pivot.ItemsSourceProperty, "SelectedItem", "SelectionChanged")
            .ApplyBinding =
            (viewModelType, path, property, element, convention) =>
            {
                if (ConventionManager
                    .GetElementConvention(typeof (ItemsControl))
                    .ApplyBinding(viewModelType, path, property, element, convention))
                {
                    ConventionManager
                        .ConfigureSelectedItem(element, Pivot.SelectedItemProperty, viewModelType, path);
                    ConventionManager
                        .ApplyHeaderTemplate(element, Pivot.HeaderTemplateProperty, null, viewModelType);
                    return true;
                }

                return false;
            };

        ConventionManager.AddElementConvention<Panorama>(Panorama.ItemsSourceProperty, "SelectedItem",
            "SelectionChanged").ApplyBinding =
            (viewModelType, path, property, element, convention) =>
            {
                if (ConventionManager
                    .GetElementConvention(typeof (ItemsControl))
                    .ApplyBinding(viewModelType, path, property, element, convention))
                {
                    ConventionManager
                        .ConfigureSelectedItem(element, Panorama.SelectedItemProperty, viewModelType, path);
                    ConventionManager
                        .ApplyHeaderTemplate(element, Panorama.HeaderTemplateProperty, null, viewModelType);
                    return true;
                }

                return false;
            };
    }
}

Before testing our work, there’s one important thing to do: enable Fast App Resume in the manifest. Unfortunately, this option isn’t supported by the visual editor, but you’ll have to manually edit the XML file: right click on the WMAppManifest.xml file in the Properties folder of your project and choose View code. You’ll find the following section:

<Tasks>
  <DefaultTask Name="_default" NavigationPage="Views/MainPage.xaml" />
</Tasks>

To enable Fast App Resume you’ll have to add a new attribute to the DefaultTask node called ActivationPolicy and set it to Resume, like in the following sample:

<Tasks>
  <DefaultTask Name="_default" NavigationPage="Views/MainPage.xaml" ActivationPolicy="Resume" />
</Tasks>

That’s all! If you want to do some experiments with Fast App Resume, you can use the sample attached project, which simply contains two pages: the first page contains a button to navigate to the second one, which instead is empty. This project has enabled Fast App Resume, so you’ll notice that, if you navigate to the second page and you suspend the app by pressing the Start button, then you open it again using the main tile or the icon in the application list, you’ll notice that the previous instance of the app will be correctly resumed and you’ll land to the second page, instead of the main one.

Happy coding!

Posted in Windows Phone | Tagged , , | Leave a comment

Windows Phone and Windows Store apps developers unification

Yesterday Microsoft announced the first step towards the long rumored Store unification between Windows Phone and Windows 8: a unique registration process. What does it mean? Until today, being a Windows Phone developer was different than being a Windows Store apps developer: they were two separate subscriptions, each with their own registration process and payment.

Starting from today, instead, the process has been unified: a single registration portal, a single registration process and, most of all, a single registration fee! Microsoft is doing an amazing job to attract developers to its new platforms: first they’ve dropped the registration price (from 99 $ to 15 $), now they’ve merged the registration process and they’ve lowered it by 70% of the original price. The new developer fee to pay, in fact, is 19 $, which will allow you to publish applications both for Windows Phone and Windows 8.

For the moment, Microsoft has unified just the registration process: since we’re talking about two different Stores (you can’t install a Windows Phone app on Windows 8 and vice versa), you will still have to use two different dashboards to publish and manage your applications on the store. So, if you’re a Windows Phone developer, your starting point will continue to be http://dev.windowsphone.com

And what about already existing developers? The good news is that, for free, you’ll gain access to both stores: so, if you were a Windows Phone developer, now you’ll be able to submit apps also on the Windows 8 store; if you were a Windows Store apps developer, you’ll be able to port and publish your apps also on the Windows Phone Store. And if you were already both? Microsoft got you cover, by giving you a free token to renew your subscription when your account will expire (the account that expires for latest will count).

This news, combined with the announcements by Nokia that is going to release its first Windows RT tablet, will help more developers to support both platforms, by giving them the tools to publish them both for smartphones and PCs / tablets. As I’ve already made in the previous post about the Nokia World, I suggest you take a look at this series of webcasts about sharing code between Windows Phone and Windows Store applications.

Keep up the good work!

Posted in Windows Phone | Tagged , | Leave a comment