9

App Monitoring

In the mobile development world, it's very important to iterate fast—users want new features and expect quality, and if you can't deliver on those expectations, you'll certainly feel it in your ratings and reviews. One of the best ways to ensure that you're shipping quality apps and features is to employ DevOps.

DevOps is where the technical and operational sides of app development meet. Proper DevOps integrates business operations with tools, resulting in a more automated and continuous release process. DevOps tools typically combine continuous integration and delivery (CI/CD)—the automation of the building, testing, and distribution of your app—with monitoring capabilities. CI/CD and monitoring together create a seamless loop, where CI/CD provides an output of testable features, and monitoring provides an input of feedback and analytics on those features. This continuous loop, when implemented properly, enables development teams to rapidly release new features that maintain the quality their users expect.

In this last chapter of the book, we'll focus on analytics and crash reporting tools, and how they can help you continuously monitor and improve your app. Specifically, we'll take a look at Visual Studio App Center and how to integrate its SDK libraries into the TripLog Xamarin.Forms mobile app that we have created in this book.

In this chapter, we will cover the following topics:

  • Mobile app analytics and crash reporting
  • Adding monitoring capabilities to the TripLog app with the Visual Studio App Center SDK

We'll start by going over the benefits of collecting analytics in a mobile app.

Mobile app analytics

Application analytics and crash reporting tools have been around for a long time. The idea of application analytics is to collect data about your users, their behavior within your application, the features they use—or don't use—and how often they use those features or the application itself. The idea of crash reporting is to collect crash or error data from within the application. In both cases, the information collected is typically aggregated into a single dashboard-like interface, so that you and other members on the application team can analyze it.

Application analytics are also extremely important to a product's life cycle and its stakeholders, as they provide real insight into the application and can help drive key business decisions about the product. For example, a feature that was thought to be very important to users might show up in analytics data as something that users aren't actually utilizing as much as anticipated. From there, the decision needs to be made whether this is because the feature is undiscoverable, or simply not as important to the users as anticipated. On the other hand, analytics might indicate that a specific feature or area within your application is being used or accessed far more than expected. This would tell the product owners and developers that focusing on that feature or area should be a priority.

Crash reporting

The power of a crash reporting tool is that it automatically captures the exception and stack trace information. Without this type of capability, you as a developer are left to rely on your end user to report the bug or error. In some cases, they may not even report the error and will instead simply close your app, and you will have no idea the bug even exists. Assuming that your users do report back to you about a bug or error they witnessed in the application, you are still relying on them to provide you with accurate information and are left trying to reproduce the error. Not only is this a potentially inaccurate process, but it is also time-consuming and cumbersome. It puts a burden on your users, as well as on you and your development team.

Having a crash reporting tool in place allows you to handle bugs and errors in real time, which is much faster than relying on users. If a user does experience a bug and reports it to you, having the crash reporting tool integrated within your app allows you to easily find the data related to the error they ran into. Furthermore, if you have both app analytics and crash reporting in your application, you can often leverage the analytics to identify the specific path the user took within the application before running into the issue.

There are several tools on the market. Some only do analytics, others only do crash reporting, and, of course, some do both. Most of these tools support .NET, and several specifically support Xamarin, making it easy to integrate them into mobile applications built with Xamarin. Microsoft's Visual Studio App Center is a service that offers analytics, error, and crash reporting tools, on top of a suite of automated build, distribution, and testing tools.

Visual Studio App Center

Visual Studio App Center is a service provided by Microsoft that offers a comprehensive mobile DevOps toolchain. One of the biggest barriers to entry when it comes to setting up DevOps tooling is the amount of configuration, integration, and maintenance that's involved. In my experience, setting up DevOps tools means integrating several services, writing tons of scripts, and, typically, dedicating a developer to maintaining the build server. App Center offers a streamlined solution that minimizes configuration and pretty much eliminates integration and maintenance, since it's a centralized and hosted service.

All of the components of App Center can be accessed via the App Center website or API. The monitoring components also require the App Center SDK to be included in your mobile app package. For Xamarin apps, the SDK is available via NuGet.

This chapter is primarily focused on the app monitoring tools within Visual Studio App Center. To learn more about all of the tools and features of Visual Studio App Center, visit http://appcenter.ms.

Setting up Visual Studio App Center

If you don't already have an App Center account, you'll need to create one. Once you have signed in to App Center, create a new app for each platform you will be delivering your mobile app on. Each app you create in App Center will be associated with a unique identifier known as an app secret. These app secrets are required when using the App Center SDK within your mobile app.

Creating an analytics service

In order to use the App Center SDK in our TripLog app, we will want to abstract it into a service, like we did for geolocation. As we saw multiple times in previous chapters, there are numerous benefits to this approach, namely, it loosely couples our ViewModels from the actual code that uses the App Center SDK, making unit testing our ViewModels much simpler and cleaner.

In order to create an analytics service, perform the following steps:

  1. First, create a new interface named IAnalyticsService in the Services folder of the core library project:
    public interface IAnalyticsService
    {
    }
    
  1. Next, update the IAnalyticsService interface with methods to track usage events and errors:
    public interface IAnalyticsService
    {
        void TrackEvent(string eventKey); 
        void TrackEvent(string eventKey, IDictionary<string, string> data); 
        void TrackError(Exception exception); 
        void TrackError(Exception exception, IDictionary<string, string> data);
    }
    

Notice that in the preceding code, the methods in this service are not necessarily specific to App Center—they represent a pretty generic functionality when it comes to event and error tracking. This leads to yet another benefit of the loosely coupled architecture that we have put in place: if, for some reason, you need to stop using App Center Analytics and use another app analytics toolset instead, simply write a new implementation of this interface, and your ViewModels will automatically be ready to use the new implementation, since they use it through the IAnalyticsService interface. Unit tests for ViewModels that have a dependency on IAnalyticsService also require no change if the concrete implementation changes, and they'll provide validation that the ViewModels haven't started failing as a result of swapping out implementations.

For now, we will, of course, use App Center in our concrete implementation of the IAnalyticsService interface. The App Center Analytics and Crashes API is pretty simple and straightforward, and so the implementation for each of the methods in the interface is no more than a couple of lines of code. Specifically, the Analytics.TrackEvent and Crashes.TrackError methods allow us to send user events and exceptions to App Center, which are then visible within the App Center portal. In order to create the App Center implementation of IAnalyticsService, perform the following steps:

  1. Add the Microsoft.AppCenter.Analytics and Microsoft.AppCenter.Crashes NuGet packages to the core project and each of the platform-specific projects.
  2. Start the SDK using your provided app secrets for each platform, in the OnStart method override in the App class (App.xaml.cs):
    using Microsoft.AppCenter;
    using Microsoft.AppCenter.Crashes;
    using Microsoft.AppCenter.Analytics;
    public partial class App : Application
    {
        // ...
        protected override void OnStart()
        {
            AppCenter.Start("ios={Your iOS app secret here};"
                + "android={Your Android app secret here};"
                + "uwp={Your UWP app secret here}", 
                typeof(Analytics), typeof(Crashes));
        }
        // ...
    }
    
  3. Create a new class named AppCenterAnalyticsService in the Services folder, in the core library, that implements IAnalyticsService:
    public class AppCenterAnalyticsService : IAnalyticsService
    {
    }
    
  4. Next, implement the members of IAnalyticsService within the AppCenterAnalyticsService class:
    using System.Collections.Generic;
    using Microsoft.AppCenter.Analytics;
    using Microsoft.AppCenter.Crashes;
    public class AppCenterAnalyticsService : IAnalyticsService
    {
        public void TrackEvent(string eventKey)
        {
            Analytics.TrackEvent(eventKey);
        }
        public void TrackEvent(string eventKey, IDictionary<string, string> data)
        {
            Analytics.TrackEvent(eventKey, data);
        }
        public void TrackError(Exception exception)
        {
            Crashes.TrackError(exception);
        }
        public void TrackError(Exception exception, IDictionary<string, string> data)
        {
            Crashes.TrackError(exception, data);
        }
    }
    
  1. Next, update the TripLogCoreModule Ninject Module in the core library, to register the AppCenterAnalyticsService implementation in the IoC:
    public class TripLogCoreModule : NinjectModule
    {
        public override void Load()
        {
            // ViewModels
            // ...
            // Core Services
            // ...
            Bind<IAnalyticsService>()
                .To<AppCenterAnalyticsService>()
                .InSingletonScope();
        }
    }
    

Next, we'll need to be able to use this new analytics service within the logic of our app; specifically, the ViewModels. Since we'll likely need to report analytics data from all of our ViewModels, it would be best to just include an instance of IAnalyticsService as a protected property of the BaseViewModel, similar to the INavService property, and include it in the constructor's parameter list, as follows:

  1. Add a protected IAnalyticsService property to BaseViewModel, named AnalyticsService, and add an IAnalyticsService parameter to the constructor, which will set the protected property:
    public abstract class BaseViewModel : INotifyPropertyChanged
    {
        protected INavService NavService { get; private set; }
        protected IAnalyticsService AnalyticsService { get; private set; }
        protected BaseViewModel(INavService navService, IAnalyticsService analyticsService)
        {
            NavService = navService;
            AnalyticsService = analyticsService;
        }
        // ...
    }
    
  2. Next, update the constructor of the BaseViewModel<TParameter> class that subclasses BaseViewModel to take an IAnalyticsService parameter, which it simply passes to its base constructor:
    public abstract class BaseViewModel<TParameter> : BaseViewModel
    {
        protected BaseViewModel(INavService navService, IAnalyticsService analyticsService)
            : base(navService, analyticsService)
        {
        }
        // ...
    }
    
  3. Next, update the constructors of each of the ViewModels that inherit from BaseViewModel to take an IAnalyticsService parameter, which is just passed to its BaseViewModel base class.
  1. Finally, update the ViewModel instantiations in the unit test Setup methods to account for the new IAnalyticsService parameter by passing in a Mock<IAnalyticsService> object:
    [TestFixture]
    public class DetailViewModelTests
    {
        DetailViewModel _vm;
        [SetUp]
        public void Setup()
        {
            var navMock = new Mock<INavService>().Object;
            var analyticsMock = new Mock<IAnalyticsService>().Object;
            _vm = new DetailViewModel(navMock, analyticsMock);
        }
        // ...
    }
    [TestFixture]
    public class NewEntryViewModelTests
    {
        // ...
        [SetUp]
        public void Setup()
        {
            // ...
            var analyticsMock = new Mock<IAnalyticsService>().Object;
            _vm = new NewEntryViewModel(_navMock.Object, _locMock.Object, _dataMock.Object, analyticsMock);
        }
        // ...
    }
    

Now that we have created an analytics service using the App Center SDK and included it in each of the ViewModels, we can start using it to track events and exceptions, as we will see in the next section.

Tracking exceptions and events

Now that we have an IAnalyticsService property in all of our ViewModels, we can update all of our try/catch blocks to pass exceptions to App Center. For example, in MainViewModel, we have a try/finally block in the LoadEntries method that is not currently catching exceptions.

Update this try/finally block with a catch block and then pass any caught Exception off to the analytics service via the TrackError method:

void LoadEntries()
{
    if (IsBusy)
    {
        return;
    }
    IsBusy = true;
    try
    {
        // ...
    }
    catch (Exception e)
    {
        AnalyticsService.TrackError(e, new Dictionary<string, string> 
        { 
            { "Method", "MainViewModel.LoadEntries()" }
        });
    }
    finally
    {
        IsBusy = false;
    }
}

The App Center Crashes SDK automatically reports all unhandled exceptions once it is enabled in the app.

We can also start tracking user events throughout the application. For example, if we wanted to know how often users viewed the entry detail page in our app, we could call the TrackEvent method of IAnalyticsService within the Init method of DetailViewModel to log that in App Center Analytics:

public class DetailViewModel : BaseViewModel<TripLogEntry>
{
    // ...
    public override void Init(TripLogEntry parameter)
    {
        AnalyticsService.TrackEvent("Entry Detail Page", new Dictionary<string, string>
        {
            { "Title", parameter.Title }
        });
        Entry = parameter
    }
}

Summary

In this chapter, we covered the importance of app monitoring and implemented an analytics service using the Visual Studio App Center SDK. Using the analytics service, we updated the app to track errors and events, which can all be viewed in the App Center web portal.

At the beginning of this book, we started with a basic app. With each chapter we ventured into new concepts, as we refactored and added to the app code base. The app we built is not necessarily a real-world app, but the patterns used and the approaches taken are and can be applied to real-world, production apps. Early on, we introduced the MVVM pattern to separate the presentation (user interface) code from the rest of the code – the core – where the business logic lives. The immediate benefit of this pattern is that the core code becomes centralized and platform agnostic, and therefore reusable across multiple platforms. Coupled with inversion of control and dependency injection, the code becomes easily testable. The end result is a clean, organized app architecture that you can maintain and evolve with the needs of your business and end users.

Thank you so much for taking this journey with me – I hope you enjoyed reading it as much as I did writing it. I hope it helps you take your Xamarin.Forms app to the next level. I am confident that with the topics discussed in this book, the possibilities to create amazing mobile apps with Xamarin.Forms are limited only by your imagination. Happy coding!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.156.156