Do you wanna bet? I bet that you don’t the app that you recently did, on a daily basis. I would even say you don’t use it on a weekly basis. Maybe I am right, maybe I am wrong – it’s up to you to decide. The question is: is it good or bad that you don’t use the app you did? I know that sometimes we can’t use the apps we created because we are not in the target group of users. How can I use a medical app if I am not a doctor?

The reason I’ve started with this introduction is simple: how do you know how people use your app when you don’t use it?

There are several ways to track users in apps. Firstly you can record the screen of the app to see how people use it (being honest I am not a fan of this approach) Secondly, you can add analytics on the backend side, so you can assume which part of the app is being used. Furthermore, you can add some kind of analytics to log everything you want.

In this article, we will focus on the last approach. We will use Microsoft AppCentre to achieve it.

What do we want to know?

Let’s start with something simple. I would like to know which section of the app is the most popular one. On top of that, I would like to know what is the average time spent on each page. I would like that data to be anonymous – I don’t care who is who. I only need an overview what is happening.

Why do we want to know that?

As in always, I would say to help the business perform better. Having knowledge of how people use your app might help to reorder navigation, change the order of stuff, you name it. Your client may even decide to get rid of part of the app if he sees that it is not being visited. This might lead to the following conclusion:
the more we know about user behaviour in-app, the better the app can become.

If it sounds good then keep reading. The proposed solution will be for Xamarin.Forms app, but I am certain you can easily adapt it to other frameworks.

AppCenter for help!

Among all AppCenter features, there is one that we need to cover within this article – it’s events. With it, you can log whatever you want. The method used for logging looks like this (Analytics.TrackEvent(name, properties);)

/// <summary>
/// Track a custom event.
/// </summary>
/// <param name="name">An event name.</param>
/// <param name="properties">Optional properties.</param>
public static void TrackEvent (string name, IDictionary<string, string> properties = null);

Basically you have event name and properties be logged withing this event. Pretty straightforward, ain’t it?

Implementation! 👨‍💻

To begin with, you need to setup AppCenter for your app. It’s free and it will provide you with many useful features. Don’t hesitate, add it and discover its power

Track test event

Then try logging a test event. You can easily do it by running: Microsoft.AppCenter.Analytics.Analytics.TrackEvent(name);
It does not matter where you add it – just make sure this code is run. If it is, go to AppCenter and check if it is logged there. It should be visible after you tap on:


Let’s log users behaviour

In order to do it, we will need a stopwatch and service, so we won’t have to repeat our code in many places. Before we go to the code, let me warn you:

Warning
Just a friendly warning: either AppCenter is having troubles with many events or I am blind. Once, I was logging the exact time spent on-page. I ended up with something like this.

And that’s all I got. “Other” is not clickable. Because of event overload, I was missing the data. Don’t repeat my mistake. Log wisely.

End of warning

ILogger<T>

As developers, we try to write code once and maintain it in one place. For sure we wouldn’t want to have a timer in each Page class. Let’s create a service. It will have also one advantage that you can later inject it to your ViewModel.

In that interface, we’d like to be able to

public interface ILogger<T> where T : BaseViewModel
    {
        /// <summary>
        /// Log event with page name
        /// </summary>
        /// <param name="properties"></param>
        void LogEvent(Dictionary<string, string> properties = null);

        /// <summary>
        /// Start logging time on page
        /// </summary>
        void StartLogging();

        /// <summary>
        /// End logging time on page and log to AppCenter Analytics
        /// </summary>
        void EndLogging();
    }

Implementation of ILogger<T>

ublic class Logger<T> : Logger, ILogger<T> where T : BaseViewModel
{ 
    private Stopwatch stopWatch;
    
    public void LogEvent(Dictionary<string, string> properties = null)
    {
        var name = GetSectionName();
    
        if (properties != null)
        {
            Analytics.TrackEvent(name, properties);
            return;
        }
    
        Analytics.TrackEvent(name);
    }
    
    public void StartLogging()
    {
        stopWatch = new Stopwatch();
        stopWatch.Start();
    }
    
    public void EndLogging()
    {
        stopWatch.Stop();
    
        var timeElapsed = stopWatch.Elapsed.TotalMinutes;
        var timeToLog = string.Empty;
        if (timeElapsed < 1)
        {
            timeToLog = "Under 1 minute";
        }
        if (timeElapsed >= 1 && timeElapsed < 5)
        {
            timeToLog = "1-5 minutes";
        }
        if (timeElapsed >= 5 && timeElapsed < 10)
        {
            timeToLog = "5-10 minutes";
        }
        if (timeElapsed >= 10)
        {
            timeToLog = "Above 10 minutes";
        }
    
        LogEvent(new Dictionary<string, string> { { "TimeSpent on page", timeToLog } });
    }
    
    private string GetSectionName()
    {
        if (_sections.TryGetValue(typeof(T), out var name))
        {
            return name;
        }
    
        return typeof(T).Name;
    }
}

As I said in warning, AppCenter is not good at visualizing too many events. In the beginning, I was logging the exact time that the user spent on-page. That happened to be not a good approach. Later, with business people, we came up with 4 ranges that were within our interest:

  • <1minute will mean that either someone opened page by mistake, or he was checking what’s in there,
  • 1-5minutes someone was moderately interested in the content of the page,
  • 5-10minutes would mean that someone (depending on the page type) read everything
  • above 10minutes would mean that someone felt asleep.

Of course, you can adjust those ranges to your needs but remember about data overload.

Page registration

But before we call StartLogging() or LogEvent(Dictionary properties = null), I’ve decided that we need to register class for logging. You can simply do it by calling:

/// <summary>
/// Register page for Analytics
/// </summary>
/// <param name="pageType">Type of page to register</param>
/// <param name="pageName">Name of page to be shown in AppCenter Analytics</param>
public static void RegisterPage(Type pageType, string pageName)
{
    _sections.Add(pageType, pageName);
}

The usage will look like this:

Logger.RegisterPage(typeof(MainPage), "Main page");

This simply means that each event logged in MainPageViewModel will be visible in AppCenter as Main page event.

Time spent on page tracking

Now, take a look of implementation of MainPageViewModel. In it, you can see that I’ve added methods OnViewAppearing() and OnViewDisappearing() in them, I simply ask my logger to log time. Simple as that.

Logging other events

Do you want to log another kind of event? Logout? Tap on support? No problem, with the implementation of Logger you, can simply call

LogEvent(new Dictionary { { "Did user tap on add", "⛔️" } });

Business value

As I’ve stated at the beginning it is all about helping business get better. With the logging above we knew better what users were looking for. We changed the order in the app, made some things easier to access and did other minor improvements. Finally business was happier as they had a better product 😇

[mc4wp_form id=”497″]

References:

  1. GitHub sample repository (take a look at: MainPageViewModel.cs, App.xaml.cs, Logger.cs, MainPage.xaml.cs)
  2. AppCenter setup

Header image from: pixabay

Leave a Reply

Your email address will not be published. Required fields are marked *