Разработка и продвижение сравнительно серьезных мобильных приложений практически невозможна без анализа того, что делает пользователь в вашем приложении, из какого источника он произвел установку и анализа различных статистических параметров в магазине приложений. На сегодняшний день существует три основных направления в аналитике мобильных приложений:
- Трекинг источников установок (такие инструменты как Mobile App Tracking, AppsFlyer и ADXtracking, используются, как правило, для продвижения приложений);
- Аналитика внутри приложения (наиболее известные инструменты – это Flurry, Google Analytics, Яндекс.Метрика и Mixpanel, которые предоставляют возможность наблюдать за поведением пользователей внутри мобильного приложения, что позволяет принять решение о дальнейшем развитии вашего продукта);
- Сбор статистики из магазинов приложений (самые популярные сервисы – это App Annie и Distimo, позволяют отслеживать позицию в сторе как вашего приложения, так и конкурентов).
Поскольку данная статья предназначена для разработчиков, речь в ней пойдет о том, как внедрить аналитику в приложение Windows Phone. В качестве системы аналитики будет рассмотрена Flurry Analytics.
Описание сервиса
Flurry – самый популярный инструмент, в первую очередь благодаря тому, что он полностью бесплатный, доступен для всех основных мобильных платформ и имеет достаточно мощный функционал. Рассмотрим основные показатели, которые предоставляет данный инструмент:
- Количество новых и активных пользователей;
- Количество сессий и их длина;
- Частота использования приложения;
- Статистика сбоев;
- Аудитория приложения (пол, возраст, язык, география использования);
- Информация о версиях продукта и устройствах;
- События внутри приложения;
- Навигация по экранам и т.д.
Все вопросы о том, что делать с этими данными, оставим аналитикам, нас же интересует, что нужно сделать разработчику, чтобы эти данные стали доступны.
Интеграция Flurry SDK в приложение Windows Phone
После создания аккаунта на сайте https://dev.flurry.com у вас появится возможность создать новое приложение для любой из основных платформ.
Для этого Вам потребуется указать имя приложения и категорию, к которой оно относится.
Для приложения будет сгенерирован уникальный ключ и станет доступна загрузка Flurry SDK. Можно приступать к разработке!
Первым делом нужно добавить в проект ссылку на сборку FlurryWP8SDK.dll и внести некоторые изменения в манифест приложения. А именно, установить ID_CAP_NETWORKING для передачи данных аналитики на сервер Flurry и ID_CAP_IDENTITY_DEVICE для доступа к информации об устройстве.
Чтобы начать сбор аналитики, Вам потребуется при старте приложения запустить новую сессию:
private void Application_Launching(object sender, LaunchingEventArgs e)
{
FlurryWP8SDK.Api.StartSession("Your API Key");
}
В качестве параметра функция принимает уникальный ключ Вашего приложения. Также следует запускать новую сессию после повторной активации приложения:
private void Application_Activated(object sender, ActivatedEventArgs e)
{
FlurryWP8SDK.Api.StartSession("Your API Key");
}
При этом вся аналитика будет отслеживаться в рамках старой сессии. Однако, если приложение активируется после более чем 10 секунд, то создается новая сессия и аналитика будет отслеживаться уже в рамках новой сессии. Чтобы изменить срок, в течение которого старый сеанс может быть возобновлен, Вы можете использовать функцию SetSessionContinueSeconds, передав ей в качестве параметра нужное количество секунд:
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
FlurryWP8SDK.Api.SetSessionContinueSeconds(60);
}
Существует также функция принудительного завершения сессии, однако вызывать ее не обязательно, так как она по умолчанию уже связана с закрытием приложения. Но если Вам в каком-то случае потребуется завершить текущую сессию это можно сделать так же просто:
private void Application_Closing(object sender, ClosingEventArgs e)
{
FlurryWP8SDK.Api.EndSession();
}
Регистрация сбоев приложения
При обработке исключений, как правило, мы ожидаем определённый тип ошибок, но иногда возникают непредвиденные ситуации и приложение просто “падает”. В этом случае получить информацию о необработанном исключении – бесценно! Flurry предоставляет нам такую возможность:
public App()
{
UnhandledException += Application_UnhandledException;
}
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
FlurryWP8SDK.Api.LogError("Some error", e.ExceptionObject);
}
В качестве параметров функция LogError принимает сообщение об ошибке и само исключение.
Регистрация событий
Чтобы отслеживать пользовательские события, которые происходят во время сеанса, следует воспользоваться функцией LogEvent. Она имеет ряд перегрузок, это обусловлено тем, что Flurry поддерживает несколько типов событий:
- Обычные события (events);
- События с заданными параметрами (event parameters);
- События с измеряемой продолжительностью (timed event).
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
// Завершение события
FlurryWP8SDK.Api.EndTimedEvent("Timed event");
// Завершение события с параметрами
FlurryWP8SDK.Api.EndTimedEvent("Timed event with parameters");
}
protected override void OnNavigatedTo(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);
}
Как видно из кода при регистрации обычного события Вам просто надо передать уникальный идентификатор этого события в виде строки. В случае параметризованного события добавляется список параметров, который требуется связать с событием. Если же Вы хотите создать timed event (к примеру, определить, как долго пользователь находился на определенной странице, как это сделано в примере), Вам нужно передать true и когда это потребуется, завершить событие вызовом функции EndTimedEvent, передав ей тот же самый идентификатор события. Так же существует возможность связать с timed event список параметров.
Все достаточно просто, однако, есть ряд ограничений:
- Каждый проект поддерживает не более 300 событий;
- Каждое событие может иметь не более 10 параметров;
- Уникальный идентификатор события, имя параметра и значения параметра не может превышать 255 символов.
Конфигурация Flurry
В дополнение Flurry SDK имеет несколько методов конфигурации. Их следует вызывать (хотя и не обязательно) после запуска новой сессии (вызова метода StartSession).
// Устанавливает номер версии аналитических данных
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);
Продвинутый сценарий
Если при регистрации событий Вас не устраивает каждый раз в коде вызывать метод LogEvent, можно пойти на небольшую хитрость — создать вспомогательный класс для Flurry:
public class FlurryBehavior : Behavior<UIElement>
{
public string EventMessage
{
get { return (string)GetValue(EventMessageProperty); }
set { SetValue(EventMessageProperty, value); }
}
public static readonly DependencyProperty EventMessageProperty = DependencyProperty.Register("EventMessage",
typeof (string), typeof (FlurryBehavior), new PropertyMetadata(string.Empty));
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Tap += OnTap;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.Tap -= OnTap;
}
private void OnTap(object sender, GestureEventArgs gestureEventArgs)
{
if (string.IsNullOrEmpty(EventMessage)) return;
FlurryWP8SDK.Api.LogEvent(EventMessage);
}
}
Здесь мы просто подписываемся на событие Tap элемента управления и при возникновении данного события регистрируем событие на сервере Flurry. Пример использования этого класса можно посмотреть на стандартном шаблоне Panorama App:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:behaviors="clr-namespace:FlurryApp"
...
<phone:PanoramaItem Header="first item">
<phone:LongListSelector Margin="0,0,-22,0" ItemsSource="{Binding Items}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,-6,0,12">
<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap"
Style="{StaticResource PhoneTextExtraLargeStyle}"
FontSize="{StaticResource PhoneFontSizeExtraLarge}"/>
<i:Interaction.Behaviors>
<behaviors:FlurryBehavior EventMessage="{Binding LineOne}"/>
</i:Interaction.Behaviors>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</phone:PanoramaItem>
Теперь, при тапе на элементе списка у нас будет регистрироваться событие без лишнего кода.
Данный пример элементарный, но его можно улучшить:
- добавить передачу параметров;
- уникальные идентификаторы событий вынести в ресурсы;
- отслеживать события навигации по страницам приложения и т.д.
И не забудьте, что для работы данного примера, потребуется подключить к проекту сборку System.Windows.Interactivity.
Выводы
Итак, Flurry Analytics умеет измерять наиболее популярные аналитические показатели, большинство из которых можно просматривать без дополнительной настройки, что называется “из коробки”. Сервис предоставляется бесплатно, а интеграция в приложение очень проста. В качестве недостатка можно отметить не полную детализацию отчетов о сбоях в приложении и то, что обновление аналитических данных на портале требует некоторого времени (хотя это актуально и для других систем).
Используя этот инструмент в реальном проекте Тинькофф Мобильный Кошелек, на основании статистики переходов пользователей внутри приложения, мы решили отказаться от раздела “Пополнение наличными” ввиду его низкой востребованности (убедившись, что пользователи понимают, где этот раздел находится, но просто не видят в нем необходимости). В то же время раздел “Перевод на новую банковскую карту” сейчас находится достаточно глубоко, а является одним из самых популярных. В новой версии он будет ближе к основной странице и поменяет тематический раздел.