Statistics and analytics for a mobile application: using Flurry in Windows Phone 8

The development and promotion of relatively serious mobile applications is almost impossible without an analysis of what the user is doing in your application, from which source he installed and analyzed various statistical parameters in the application store. Today, there are three main areas in the analysis of mobile applications:
- Tracking installation sources (tools such as Mobile App Tracking , AppsFlyer and ADXtracking are used, as a rule, to promote applications);
- Analytics inside the application (the most famous tools are Flurry , Google Analytics , Yandex.Metrica and Mixpanel , which provide the ability to monitor user behavior inside the mobile application, which allows you to decide on the further development of your product);
- Collection of statistics from application stores (the most popular services are App Annie and Distimo , which allow you to track the position in the store of both your application and competitors).
Since this article is intended for developers, it will focus on how to integrate analytics into a Windows Phone application. As an analytics system, Flurry Analytics will be considered.
Service Description
Flurry is the most popular tool, primarily due to the fact that it is completely free, available for all major mobile platforms and has quite powerful functionality. Consider the main indicators that this tool provides:
- The number of new and active users;
- The number of sessions and their length;
- Frequency of use of the application;
- Crash statistics;
- The audience of the application (gender, age, language, geography of use);
- Information about product versions and devices;
- Events within the application;
- Screen navigation, etc.
We will leave all the questions about what to do with this data to analysts, but we are interested in what the developer needs to do to make this data available.
Flurry SDK Integration into Windows Phone App
After creating an account on https://dev.flurry.com , you will have the opportunity to create a new application for any of the main platforms.

To do this, you will need to specify the name of the application and the category to which it belongs.

A unique key will be generated for the application and the Flurry SDK download will be available. You can start development!
The first step is to add the assembly link to the project FlurryWP8SDK.dll and make some changes to the application manifest. Namely, set ID_CAP_NETWORKING to transfer analytics data to the Flurry server and ID_CAP_IDENTITY_DEVICE to access device information.
To start collecting analytics, you will need to start a new session when starting the application:
privatevoidApplication_Launching(object sender, LaunchingEventArgs e)
{
FlurryWP8SDK.Api.StartSession("Your API Key");
}
As a parameter, the function takes the unique key of your application. You should also start a new session after reactivating the application:
privatevoidApplication_Activated(object sender, ActivatedEventArgs e)
{
FlurryWP8SDK.Api.StartSession("Your API Key");
}
In this case, all analytics will be monitored in the framework of the old session. However, if the application is activated after more than 10 seconds, a new session is created and analytics will be tracked as part of the new session. To change the period during which an old session can be resumed, you can use the SetSessionContinueSeconds function, passing it the required number of seconds as a parameter:
privatevoidApplication_Deactivated(object sender, DeactivatedEventArgs e)
{
FlurryWP8SDK.Api.SetSessionContinueSeconds(60);
}

There is also a function to force a session to end, but it is not necessary to call it, since it is already connected by default to closing the application. But if in any case you need to complete the current session, this can be done as simply:
privatevoidApplication_Closing(object sender, ClosingEventArgs e)
{
FlurryWP8SDK.Api.EndSession();
}

Register application crashes
When handling exceptions, as a rule, we expect a certain type of error, but sometimes unforeseen situations arise and the application simply “crashes”. In this case, getting information about the unhandled exception is priceless! Flurry gives us this opportunity:
publicApp()
{
UnhandledException += Application_UnhandledException;
}
privatevoidApplication_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
FlurryWP8SDK.Api.LogError("Some error", e.ExceptionObject);
}
The LogError function accepts the error message and the exception itself as parameters.


Event Registration
To track user events that occur during a session, use the LogEvent function. It has a number of overloads, this is due to the fact that Flurry supports several types of events:
- Ordinary events (events);
- Events with the given parameters (event parameters);
- Events with a measured duration (timed event).
protectedoverridevoidOnNavigatedFrom(NavigationEventArgs e)
{
// Завершение события
FlurryWP8SDK.Api.EndTimedEvent("Timed event");
// Завершение события с параметрами
FlurryWP8SDK.Api.EndTimedEvent("Timed event with parameters");
}
protectedoverridevoidOnNavigatedTo(NavigationEventArgs e)
{
// Обычное событие
FlurryWP8SDK.Api.LogEvent("Simple event");
var list = new List<FlurryWP8SDK.Models.Parameter>
{
new FlurryWP8SDK.Models.Parameter("Parameter name", "Parameter value")
};
// Событие с заданными параметрами
FlurryWP8SDK.Api.LogEvent("Simple event with parameters", list);
// Событие с измеряемой продолжительностью
FlurryWP8SDK.Api.LogEvent("Timed event", true);
// Событие с измеряемой продолжительностью и параметрами
FlurryWP8SDK.Api.LogEvent("Timed event with parameters ", list, true);
}
As you can see from the code when registering a regular event, you just need to pass a unique identifier for this event as a string. In the case of a parameterized event, a list of parameters is added, which you want to associate with the event. If you want to create a timed event (for example, to determine how long the user has been on a certain page, as was done in the example), you need to pass true and when necessary, end the event by calling the EndTimedEvent function, passing it the same event identifier . It is also possible to associate a list of parameters with timed event.

Everything is quite simple, however, there are a number of limitations:
- Each project supports no more than 300 events;
- Each event can have no more than 10 parameters;
- The unique identifier of the event, the name of the parameter and the parameter value cannot exceed 255 characters.

Flurry Configuration
In addition, the Flurry SDK has several configuration methods. They should be called (although not necessarily) after starting a new session (calling the StartSession method).
// Устанавливает номер версии аналитических данных
FlurryWP8SDK.Api.SetVersion(string version);
// Устанавливает уникальный идентификатор пользователя
FlurryWP8SDK.Api.SetUserId(string userId);
// Устанавливает возраст пользователя
FlurryWP8SDK.Api.SetAge(int age);
// Устанавливает пол пользователя
FlurryWP8SDK.Api.SetGender(Gender gender);
// Устанавливает текущее местоположение пользователя
FlurryWP8SDK.Api.SetLocation(double latitude, double longitude, float accuracy);
Advanced script
If, when registering events, you are not satisfied with calling the LogEvent method every time in the code, you can take a small trick - create an auxiliary class for Flurry:
publicclassFlurryBehavior : Behavior<UIElement>
{
publicstring EventMessage
{
get { return (string)GetValue(EventMessageProperty); }
set { SetValue(EventMessageProperty, value); }
}
publicstaticreadonly DependencyProperty EventMessageProperty = DependencyProperty.Register("EventMessage",
typeof (string), typeof (FlurryBehavior), new PropertyMetadata(string.Empty));
protectedoverridevoidOnAttached()
{
base.OnAttached();
AssociatedObject.Tap += OnTap;
}
protectedoverridevoidOnDetaching()
{
base.OnDetaching();
AssociatedObject.Tap -= OnTap;
}
privatevoidOnTap(object sender, GestureEventArgs gestureEventArgs)
{
if (string.IsNullOrEmpty(EventMessage)) return;
FlurryWP8SDK.Api.LogEvent(EventMessage);
}
}
Here we simply subscribe to the Tap event of the control and when this event occurs, register the event on the Flurry server. An example of using this class can be seen on the standard Panorama App template:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:behaviors="clr-namespace:FlurryApp"
...
<phone:PanoramaItemHeader="first item"><phone:LongListSelectorMargin="0,0,-22,0"ItemsSource="{Binding Items}"><phone:LongListSelector.ItemTemplate><DataTemplate><StackPanelMargin="0,-6,0,12"><TextBlockText="{Binding LineOne}"TextWrapping="Wrap"Style="{StaticResource PhoneTextExtraLargeStyle}"FontSize="{StaticResource PhoneFontSizeExtraLarge}"/><i:Interaction.Behaviors><behaviors:FlurryBehaviorEventMessage="{Binding LineOne}"/></i:Interaction.Behaviors></StackPanel></DataTemplate></phone:LongListSelector.ItemTemplate></phone:LongListSelector></phone:PanoramaItem>
Now, with a tap on an element of the list, an event will be registered without extra code.

This example is elementary, but it can be improved:
- add parameter passing;
- uniquely identify event identifiers in resources;
- track events of navigation through the pages of the application, etc.
And do not forget that for this example to work, you will need to connect the System.Windows.Interactivity assembly to the project.
findings
So, Flurry Analytics can measure the most popular analytical indicators, most of which can be viewed without any additional settings, which is called “out of the box”. The service is free, and the integration into the application is very simple. As a drawback, one can note the incomplete detailing of crash reports in the application and the fact that updating the analytical data on the portal takes some time (although this is also true for other systems).
Using this tool in a real Tinkoff Mobile Wallet project, based on the statistics of user conversions within the application, we decided to abandon the “Cash replenishment” section due to its low demand (making sure that users understand where this section is located, but simply don’t see the need for it). At the same time, the section “Transfer to a new bank card” is now quite deep, and is one of the most popular. In the new version, it will be closer to the main page and change the thematic section.