Service-Agnostic Mobile Analytics

| | 0 Comments| 3:16 PM

Xcode 7.3 Swift 2.2

Mobile application analytics is the capture and analysis of what users are doing with your mobile app. Of course, it is a subcategory of all overall application usage analytics which covers the OS, desktop applications, web usage, and so on. Up until earlier this year, Parse was a popular cloud platform for capturing and displaying mobile app usage data.

There are a few lessons to be learned from Parse’s abrupt departure from the scene. Foremost, and this should come as no surprise to anyone who has done software development for more than year, nothing is forever. Things change. The second lesson could be, once you’ve experienced the aggravation (or pain) of changing out one framework for another, why not abstract the underlying operations a little bit and make it easier to change in the future? We’re going to take that lesson and apply it to mobile analytics and show how you can “future proof” your application a bit.


Apple’s introduction to protocols contains a very succinct definition as to what a protocol is: a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. Think about how we can use that definition to define an analytics event logger protocol. There are a few very basic methods that any logger should provide:

  • registration to the logging backend
  • log an event
  • log an event with a data dictionary

Certainly, you could go through the various analytics platform providers and find a wide variety of features, but at the core we would like to see at least these three. Perfect candidates for a protocol definition:

By itself the AnalyticsEventLogger protocol will not do anything, it is only the blueprint. We will need an actual analytics framework to do the work.


Amplitude was the first mobile analytics service we came across when looking to migrate Bondi away from Parse. It had a straightforward (and free) signup process combined with a simple API for logging events. The implementation of an AnalyticsEventLogger protocol around Amplitude would be quite simple:


CleverTap is another mobile analytics service that provides for fast sign up and registration. Truth be told, we found the actual integration of the CleverTap SDK into our application to be a bit more cumbersome. We’ll get to the reasons why in a moment, but for the sake of completeness, here is what an event logger based upon CleverTap might look like:

The key thing to notice here is that the protocol dictates the methods:

  • initialize()
  • logEvent(name:String)
  • logEvent(name:String, data:AnyObject)

The underlying implementation for an event logger based upon Amplitude will use Amplitude SDK methods. The implementation of the protocol based upon CleverTap will use CleverTap SDK methods.

Note:Many mobile analytics services provide many more methods than this. For example, some provide heatmap analysis of where on the screen the user is touching. Our goal here is not to build a protocol that encompasses all types of mobile analytics features, but a subset of those that we’ve found particularly useful.

Demonstration Application

We’ve put together a quick demonstration application that allows for you to use either Amplitude or CleverTap for event logging. This section is a walkthrough of the demonstration application with guidance on where to plug in your API keys. You will, however, have to actually sign up for the services online to run the app!

The event logger itself is kept as the instance member eventLogger of the AppDelegate.

In the above code we declare an eventLogger to be an instance of a class that adheres to the AnalyticsEventLogger protocol. The actual instance will be an AmplitudeEventLogger which we’ve outlined the implementation in the AmplitudeEventLogger.swift file. If you want to change this out to use CleverTap, simply replace the definition with:

And in truth, you don’t even need to declare the variable type (AnalyticsEventLogger) here. The Swift compiler will figure this out.

Getting the Source

Get the demonstration application source from BitBucket with git clone in a terminal. Open the appname.xcodeproj project in Xcode.

appname Project
appname Project

Project Basics

The key files to review in the demonstration project are:

  • AnalyticsEventLogger.swift – this file contains our AnalyticsEventLogger protocol that all “event loggers” will adhere to
  • AmplitudeEventLogger.swift – an implementation of the AnalyticsEventLogger protocol using the Amplitude service is here
  • CleverTapEventLogger.swift – an implementation of the AnalyticsEventLogger protocol using the CleverTap service is here
  • EventConstants.swift – event names for all of the backend services using Swift constant definitions
  • ViewController.swift – our demonstration application logs analytics events when buttons are pressed on the screen. The IBAction routines for these presses are in the view controller.
  • ApiKeys.swift – this file contains a routine we use for extract API keys from a .plist file. Details on how this is used is covered in the next section API Keys!

API Keys

Most, if not all, analytics platform will have you use either a single application key or combination of account identifier and application key. Amplitude and CleverTap are no different. The sample application utilizes property lists for managing API keys. If you haven’t signed up for any service, jump down to the sections on signing up for Amplitude or CleverTap and register for the services.

Notice that the ApiKeys.plist file above is red. That means it is missing, so you’ll need to create one to add keys for the mobile analytics providers you choose. To be able to switch back and forth between the Amplitude and CleverTap you’ll need accounts and API keys for both. You can follow though the instructions below to obtain those, or, even use the starter application as a template to try out other services such as Flurry or AppAnalytics.

Create the ApiKeys.plist file using Xcode File – New – File and then select iOS Resource, and choose the Property List template. Click Next and name the file ApiKeys.plist and ensure that the dialog box includes adding it to the application target.

Add keys for AmplitudeDevelopmentApplicationKey etc., one for each key that you will need to reference in the project. If you follow through with this example and use Amplitude and CleverTap, your ApiKeys.plist file should look something like this:


Once the API keys are in place, update the AppDelegate to choose the logger you want to use and then run the application either on a phone or the simulator.

Logging Events
Logging Events

Pressing on the Like, Dislike, etc. buttons will call the mobile analytics logging methods (see the ViewController.swift file). In the case of the Donate button the logged method will include the amount donated.

Getting Started with Amplitude

Note: This a quick introduction to signing up for Amplitude and is not meant to be a full-featured tutorial on all of its features.

First, you’ll need to sign up for Amplitude on their sign up page. Fill in all of the required information (name, email, etc.), and get greeted with a Welcome to Amplitude dialog.


Click on the Let’s Go button and create your first application. We’re going to put in our organization as LLC and the application will be Appname Development. There will be different “keys” for development vs. release applications.


Click Continue and select the iOS SDK and click I’m Ready to Install. Amplitude will present a Install the Amplitude SDK page which provides a set of instructions for downloading the iOS SDK, updating your projects build settings to include SQLite, and then showing an Objective C example of invoking the service. We’re passionate about using Swift for applications, so at this stage click on the Download the source code link to pull down the iOS source for Amplitude. Unzip the downloaded folder.

The demonstration application provided already contains the Amplitude SDK, but if you were starting a new project drag and drop the Amplitude subfolder into your project. Make sure and select Copy items if needed, Create groups, and of course ensure your application target is selected.


Back in the Amplitude portal you can just click Continue on the Install Amplitude SDK page and then click Done, and then when prompted to invite members to your team click Skip.

Add Additional Frameworks

Add the following frameworks to your Xcode Project:

  • libsqlite.tbd

Frameworks are easily added by going to your project target application and then selecting Build Phases, then going to the Link Binary With Libraries and then using the + icon to select the framework.

Add a Bridging Header

At we’ve been using Swift since the day it came out and haven’t looked back. If you too are developing your applications with Swift you’ll need to add a bridging header to your project to access the Amplitude API. Bridging headers are easy to add. First, use File – New – File and select iOS Source, and then find the Header file icon. Name the file bridgingHeader.h.

Next, go to your application target and click on Build Settings. Type bridging into the search box to see something like:

Bridging Header
Bridging Header

Double-click on the line that says Objective-C Bridging Header and type into the dialog box $(SRCROOT)/bridgingHeader.h. The $(SRCROOT) variable will be expanded to your project’s source root .

Now, in the bridgingHeader.h add the line #import "Amplitude.h".

API Credentials

The API credentials you will need for your application are easy to find in Amplitude. In the web portal, click on the account e-mail in the upper-right and select Account Settings in the dropdown menu.

Amplitude API Keys
Amplitude API Keys

In our demonstration application we’re using the .plist method for storing API keys, so take the appropriate key and add to the ApiKeys.plist file. Alternatively you can put the API key directly in the Amplitude.instance.initializeApiKey method in the AmplitudeEventLogger.swift file.

Getting Started With CleverTap

Note: This a quick introduction to signing up for CleverTap and is not meant to be a full-featured tutorial on all of its features.

We found working with CleverTap to be a little less intuitive than Amplitude. Nevertheless, it doesn’t require a credit card to get started which makes it easy to try-before-you-might-buy.

Sign up with CleverTap by heading over to Sign Up page and filling out the required information. You’ll get an activation e-mail sent which contains a link to complete the sign up process. Find the e-mail and click on the Complete your signup button.


Click the Add my first app button to take you to the next screen:

Add Your App
Add Your App

Notice that in CleverTap a TEST environment automatically gets created for your application. Frankly I don’t care for this feature because it makes assumptions about what your environments are named. With Amplitude you would manage your own development vs. staging vs. release applications, whereas CleverTap simply assumes you’ll have a TEST- application.

Click on Add My App. You’ll be presented with a screen where you can select which ecosystem you’re developing for (Android, iOS, Windows, etc.) and provide the AppStore URL for your application. Select iOS and click on Skip URL.

Here too the integration instructions for CleverTap are not as straightforward as they could be. We suggest you click on Skip Integration and then follow these instructions:

Obtain the CleverTap iOS SDK

A download link to the CleverTap iOS SDK can be found on the iOS SDK integration page. Choose the download for either Xcode 7 or Xcode 6, and a file named something like will be placed in your Downloads folder. Unzip the file and a single framework file CleverTapSDK.framework will be there in the Downloads folder. Drag and drop the CleverTapSDK.framework file to your Xcode project ensuring that Copy items if necessary and Create groups is selected, and of course you will want to add it to your application target.

Add Additional Frameworks

Add the following frameworks to your Xcode Project:

  • SystemConfiguration
  • CoreTelephony
  • Security
  • UIKit
  • CoreLocation

Add a Bridging Header (If You’re Using Swift)

As with Amplitude, if you are using Swift you will want to add a bridging header. Refer back for quick instructions on adding the header file. In the bridgingHeader.h add the line #import <CleverTapSDK/CleverTap.h>.

API Credentials

CleverTap tries to be a bit too clever with its API keys. There is a method that can be called, autoIntegrate, that “registers everything” with the CleverTap backend. There are no arguments to the autoIntegrate method and its only after looking closely at this

CleverTap Autointegrate
CleverTap Autointegrate

that it is clear you need to add two keys CleverTapAccountID and CleverTapToken to “your .plist file”. One assumes that is referring to the Info.plist file, but if you are going to manage a test application and regular application, juggling .plist files in conditional builds is annoying. So rather than use the autoIntegrate method you can use changeCredentials(withAccountID:andToken). This skips the auto-integration and need for using .plist files to manage the API keys. Instead you can use something like:

Note: The valueForAPIKey routine comes from our post on managing API keys with property lists, but using this method you can determine the name of the key.

Closing Thoughts

Software developers are interesting creatures. We frequently want to rewrite things when there is a new language or framework to work with, yet we don’t necessarily care for changing things when its forced on us. There is also a desire to develop “systems” that are extensible and can adapt to tomorrow’s requirements. Our service-agnostic event logging follows the spirit of this approach, but even still one must recognize that tomorrow’s mobile analytics platforms will provide us with new features and capabilities that require adapting to if they are to be utilized. In other words, the approach we used here is by no means the final story, and as new services are evaluated we must always be prepared to rework areas of the code that are no longer capable of fitting our needs. Even still, after you’ve been through the headache of changing APIs due to one reason or another (your favorite API is abandoned, isn’t Swifty enough for you, or otherwise end-of-lifed like Parse), you might consider using a protocol-based approach to provide a neutral shim between you and another service.

Leave a Reply

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