Google Analytics now also on your Windows Phone 8 app in 1 minute

Yes today I released the Google Analytics NuGet package that supports Windows Phone 8. It’s part of the same NuGet package of the version for Windows Phone 7. I’ve heard that creating an app account doesn’t work any longer with Windows Phone apps, though you can fake it into a website. But for the detailed three steps I recommend reading my previous post. The fast track?

Open the NuGet Package Manager Console and type:

Install-Package MSAF.GoogleAnalytics
Have fun!

Google Analytics on your Windows Phone App in 1 minute

Yes 1 minute. So let’s start immediately.

1 - Open the NuGet Package Manager Console and type:

Install-Package MSAF.GoogleAnalytics

2 - Next, register a new application / web property inside Google Analytics.

image

Then copy the Property ID that starts with UA-.

3 - Past that Property ID inside the App.xaml at this place.

<analytics:GoogleAnalyticsService WebPropertyId="UA-12345-6" />

That’s it. Yes, totally. And? Did you do it under the minute?

Background information

I’ve been in contact with Michael Scherotter for some time about NuGet and MSAF, thanks for the support Michael. Basically the MSAF project is really powerful and can be applied to your Windows Phone project quite easily when you know how to do this. I’ve written about it a couple of times. However when we upgraded to Mango all dlls were upgraded except the Google.WebAnalytics dll. The mismatch in versions was causing a lot of problems because some libraries were asking for a 7.0 version of System.Windows.Interactivity and some were asking for the 7.1 version. I fixed that for the NuGet release, everything is 7.1 based.

Advanced tracking

I also added the code to track a little bit of basic information. You can find that in the GoogleAnalyticsService class in the Analytics folder after applying the NuGet package. There is support for up to 5 Custom Variables. Yes I removed the AppId/ProductId that’s included by default leaving only 4 Custom Variables. You can still add the AppId Custom Variable by your own choice, but I removed it because I have one Google Analytics Web Property per App, so it was useless.

When you want to track your analytics from for example your ViewModel you do something like this.

IAnalyticsTracker tracker = new AnalyticsTracker();
tracker.Track("EventCategory","EventName","EventValue optional");

Statistics for your Windows Phone application (Google Analytics)

Update 06-07-2012: The world has changed. You can now do it in 1 minute!

Alright, I’ve tried a couple of different systems to get the statistics for the apps I created.

Google Analytics custom way

I started more than a year ago with a unreliable option using Google Analytics. This option was unreliable because it didn’t handle things like no connectivity and was depending on the WebBrowser control. Technically this was an option, but there are better options.

Flurry Analytics

My first applications actually did go live with Flurry Analytics for the stats. This worked perfectly fine for some time, until I introduced a application version that only supported Mango. Strangely I never got stats for that version. In the end I heard more people complaining that the Flurry Analytics library didn’t work with Phones running on Mango. I was not happy because it took weeks before I got a response from Flurry about the problem. They asked if I was interested in doing some beta-testing. I honestly didn’t have interest in beta-testing after that long time. I hear some rumors that it’s still not working, but I’m not sure, I’ve given up Flurry Analytics.

PreEmptive Runtime Intelligence

Alright, then I heard people say, why don’t you use PreEmptive’s Runtime Intelligence. It’s free and actually an Enterprise Product. I tried it, and actually liked it. The documentation on how to use it was not top-level, but with a little bit of trying out I got things working. But even better the tool integrates an Obfuscation tool to obfuscate the code. But then it started to take longer to get the stats processed. The last time my stats were processed is at October 6th, that’s 13 days ago, way to long. I understand that it can take some time, 24 hours is pretty acceptable. But more, every user of Runtime Intelligence got an e-mail to say that the conditions are about to change in two months time. This is basically because Microsoft has changed the contract with PreEmptive, but still, the new conditions are not clear, yet. Will it be paid, will it be limited? We don’t know yet. So for me, it’s time to look for a solid Analytics solution that I know will be free and will be supported by tools in the market.

Google Analytics with Microsoft Silverlight Analytics Framework

Alright, I’ve chosen to go back to Google Analytics and follow the comments I got from my readers on my custom Google Analytics tracking post. They suggest to make use of Microsoft Silverlight Analytics Framework. This framework supports a couple of very important scenario’s.

  • Offline scenarios
  • Support for multiple analytics services, including:
    • Comscore
    • Google Analytics
    • PreEmptive Solutions

Where I already have experience with implementing analytics using the custom PreEmptive tools I wouldn’t try that again, how long will it be free? I also have some experience with Comscore for one of my customers. I don’t understand how to read the reports so that’s not really an option for me, neither is it free. So Google Analytics it is, I know how to read the reports, and I’ve got a lot of experience implementing it for websites. Let’s start with the implementation in a Windows Phone application.

Step 1 Downloading and Referencing

You can download the source or the installation package. Be aware that the source doesn’t contain the source code for the Analytics Services like Google Analytics. So recommended will be the download of the installation package. After the installation you can find the libraries in: C:\Program Files (x86)\Microsoft SDKs\Microsoft Silverlight Analytics Framework\

You’ll need to reference the following libraries when working with Google Analytics:

  • Microsoft.WebAnalytics.dll
  • Microsoft.WebAnalytics.Behaviors.dll
  • System.ComponentModel.Composition.dll
  • System.ComponentModel.Composition.Initialization.dll
  • System.Windows.Interactivity.dll

Note: I’ve had some trouble with conflicting System.Windows.Interactivity libraries. It’s distributed with Expression Blend, MVVM Light and also with the Microsoft Silverlight Analytics Framework. I think there needs to be a solution so that the distribution should no longer be required for the different frameworks. I specially had a conflict when using Microsoft Silverlight Analytics Framework (made for Windows Phone SDK 7.0) in combination with MVVM Light 4 Preview (made for Windows Phone SDK 7.1). I did fallback to the previous version of MVVM Light 3 to remove the conflict.

Step 2 Create the IApplicationService and use reference it in App.xaml

Let’s start with gathering some generic information I want to gather from my users. To be honest I want to do this for all my applications. So this static class get's some information about the device. The PhoneHelper class can be found inside the Coding4fun library which also has other nice stuff. You could use this also for difference between Trial and Paying users.

public static class AnalyticsProperties
{
    public static string DeviceId
    {
        get
        {
            var value = (byte[]) DeviceExtendedProperties.GetValue("DeviceUniqueId");
            return Convert.ToBase64String(value);
        }
    }

    public static string DeviceManufacturer
    {
        get { return DeviceExtendedProperties.GetValue("DeviceManufacturer").ToString(); }
    }

    public static string DeviceType
    {
        get { return DeviceExtendedProperties.GetValue("DeviceName").ToString(); }
    }

    public static string Device
    {
        get { return string.Format("{0} - {1}", DeviceManufacturer, DeviceType); }
    }

    public static string OsVersion
    {
        get { return string.Format("WP {0}", Environment.OSVersion.Version); }
    }

    public static string ApplicationVersion
    {
        get { return PhoneHelper.GetAppAttribute("Version").Replace(".0.0", ""); }
    }
}

So let’s continue with our IApplicationService that wraps the WebAnalyticsService provided by the Analytics Framework. Just to prevent that my applications start to depend to much on Microsoft Silverlight Analytics Framework, I don’t want to change too much code when I need or want to switch next time. I explicitly set the Page Tracking to false because I want to be in control when and what to track. Further more I’m setting the CustomVariables that you might recognize from Google Analytics. There is a maximum of 5 Custom Variables and because the GoogleAnalytics library also puts the ApplicationId inside the Custom Variables you end up having only four for your application. That’s one of the reasons why I have the Device Type and Manufacturer concatenated in the Device property, choose carefully what you want to track. Next is the interesting part of Initializing MEF, I’m not an expert on MEF but basically it’s a kind of IoC container but differently. We will make use of the composition possibilities that we get from using MEF in a moment. The last part is the WebPropertyId which is passed to Google Analytics, this is the Google Analytics Property Id which is in the form of UA-XXXXX-X. So make sure you register a Google Analytics Web Property

public class AnalyticsService : IApplicationService
{
    private readonly IApplicationService _innerService;
    private readonly GoogleAnalytics _googleAnalytics;

    public AnalyticsService()
    {
        _googleAnalytics = new GoogleAnalytics();
        _googleAnalytics.CustomVariables.Add(new PropertyValue { PropertyName = "Device ID", Value = AnalyticsProperties.DeviceId });
        _googleAnalytics.CustomVariables.Add(new PropertyValue { PropertyName = "Application Version", Value = AnalyticsProperties.ApplicationVersion });
        _googleAnalytics.CustomVariables.Add(new PropertyValue { PropertyName = "Device OS", Value = AnalyticsProperties.OsVersion });
        _googleAnalytics.CustomVariables.Add(new PropertyValue { PropertyName = "Device", Value = AnalyticsProperties.Device });
        _innerService = new WebAnalyticsService
                            {
                                IsPageTrackingEnabled = false,
                                Services = { _googleAnalytics, }
                            };
    }

    public string WebPropertyId
    {
        get { return _googleAnalytics.WebPropertyId; }
        set { _googleAnalytics.WebPropertyId = value; }
    }

    #region IApplicationService Members

    public void StartService(ApplicationServiceContext context)
    {
        CompositionHost.Initialize(
            new AssemblyCatalog(
                Application.Current.GetType().Assembly),
            new AssemblyCatalog(typeof(AnalyticsEvent).Assembly),
            new AssemblyCatalog(typeof(TrackAction).Assembly));
        _innerService.StartService(context);
    }

    public void StopService()
    {
        _innerService.StopService();
    }

    #endregion
}

You can then add this ApplicationService to the ApplicationLifetimeObjects in the App.xaml file.

<Application.ApplicationLifetimeObjects>
    <!--Required object that handles lifetime events for the application-->
    <shell:PhoneApplicationService Launching="ApplicationLaunching"
                                    Closing="ApplicationClosing"
                                    Activated="ApplicationActivated"
                                    Deactivated="ApplicationDeactivated" />
    <Analytics:AnalyticsService WebPropertyId="UA-XXXXX-X" />
</Application.ApplicationLifetimeObjects>

This also enables automatic tracking Launch, Closing, Activated and Deactivated events in Google Analytics. So we don’t have to do anything manually to enable that part.

image

Step 3 Start tracking usage of features

Besides the starting and stopping of your application you probably want to track the usage of features in your app. You can make use of the TrackAction Behavior for example which can be found in Microsoft.WebAnalytics.Behaviors. But I actually like to have this kind of stuff in code which makes it easier for me to get an overview of what I’m tracking. So I wrote this simple AnalyticsTracker class that makes use of MEF to import the WebAnalytics stuff.

public class AnalyticsTracker
{
    public AnalyticsTracker()
    {
        CompositionInitializer.SatisfyImports(this);
    }

    [Import("Log")]
    public Action<AnalyticsEvent> Log { get; set; }

    public void Track(string category, string name)
    {
        Track(category, name, null);
    }

    public void Track(string category, string name, string actionValue)
    {
        Log(new AnalyticsEvent { Category = category, Name = name, ObjectName = actionValue });
    }
}

Usage is pretty straightforward.

AnalyticsTracker tracker = new AnalyticsTracker();
tracker.Track("Advertisement", "Refreshed", adUnit);

Step 4 Analyse the data

Alright start with Top Events

image

Cool but in which countries?

image

Of course there much more analytics that you can see inside of Google Analytics, this is just a start.

Dependency Injection using Unity

Just about two weeks ago the Microsoft patterns & practices team released a Community Technology Preview of the Unity project. Unity is a lightweight Dependency Injection Container. I've just been using it in some very basic scenario's, so far I like it. It has support for constructor and property injection. But also, a thing not many Dependency Injection container support I think, the ability to do method call injection.

David Hayden has some post on Unity on his blog. But most of all he has created a screencast on Unity, very nice to get an introduction to Unity.

Unity already gets some attention on the Internet. Oren Eini, a guy that's very experienced on Dependency Injection and did some coding on Castle Windsor another Dependency Injection container, has done a review on Unity.

Let's wait for the final release. Maybe I will add it to my toolbox. It still seams customers like open source projects from Microsoft more than open source projects from different hand. Maybe I will be able to apply Dependency Injection using Unity at a customers place.

IoC Container instance sharing

I haven't been able to use an IoC container on a real-world project yet. And even though I've been doing some research on it, I still have questions regarding IoC container usage.

I always thought about using the Application var for storing the container instance for an ASP.NET application. For other application I would use a static class or static var for the container instance. But thinking about this more and more, I'm not sure about this approach.

What approach do you think is the most sufficient way to share the container instance? Or should we not even share the container instance at all?