Often you’ll need to know how many active users you have and what functionalities of your app that they use the most. If you’re writing an iOS or Android app, there’s plenty of services to do this. But on the Mac choices are a bit slim.
I needed some kind of application usage analytics service that I can use for our upcoming Mac OS X application. I’ve been using Flurry Analytics for my iOS apps but it looks like they don’t provide an Mac OS X counterpart to their service. Similarly Google Mobile Analytics also doesn’t have a desktop counterpart.
Then I’ve integrated this framework into my app and distributed the app to just over a hundred beta users. Strangely Google Analytics’ reports for that “app” remained zero hits. That can’t be right since I’ve been receiving feedback from a number of users (meaning that at least some people are using the app, even if only for a short while). I’ve also debug the app with analytics turned on – even if nobody else uses the app, the reports should show my own usage of the app. I’ve fiddled with it for a while, trying out various type of tracking codes (e.g. site tracking vs mobile tracking), debug the library and immediately checking the result but it simply doesn’t work: there isn’t any “hit” registered in any of the Real-Time Reports.
What puzzles me is that the answerer claims that this library works perfectly fine. I’m not sure whether there’s some hidden tricks to use doo’s library that I didn’t know about or that this answer was simply lying:
I was using the latest version of
ga.js and try it out. Unfortunately it didn’t work.
Being weary for this and having a real need for a desktop analytics library, I decided to roll out my own solution:
BSWebTracker. It’s still roughly inspired from doo’s work but completely written from scratch with an entirely different approach. It’s not tightly coupled to Google Analytics and you can easily swap in another analytics provider (Adobe’s SiteCatalyst is one contender – previously Omniture). But it does require you to have a web server as part of the setup.
How it works
BSWebTracker is designed only to load a single URL for the entire app and differentiates various tracking actions by varying Analytics’
utm_xxx parameters. These are the exact same parameters that you can construct using the URL Builder.
Since it uses a
This imply that you shouldn’t send hundreds of tracking requests in a tight loop – otherwise it may take a very long time for all requests to complete and the user may quit your application long before all tracking requests are sent. Instead send on the completion of a user action like, for example, opening a document or completed a workflow.
BSWebTracker also manages its
WebView instance diligently. It’ll discard the instance whenever there are no more tracking requests to send. You wouldn’t want to keep an unused WebView instance around, would you? It’s a heavyweight object – being a full-fledged web browser after all. So even though you shouldn’t burst a lot of requests, you’ll still want to keep them near (time-wise) to each other. In other words, maintain locality of reference. Try to group tracking requests in one lifecycle of your app – for example at startup – instead of sending far-flung requests. If you send requests only once in a while, there might be thrashing of
WebView instance creation / destruction as the class creates a WebView instance to solely serve one request and then immediately deallocates it afterwards.
The sequence diagram below illustrates the typical flow of messages between your application,
BSWebTracker, and how your tracking data finally ends up in Google.
As you can see from the diagram above, each time your application sends a tracking request, the class will just queue it for later. At the next run loop, it’ll pick up one request and send them over to the
WebView. In turn the
WebView will load the request and eventually Google Analytics gets to see your tracking request. After the
WebView have completed a request, BSWebTracker will pickup another URL from the queue and send them over. This will continue until the last tracking request is completed. Should BSWebTracker tries to dequeue and see that the queue is empty, it’ll discards the WebView instance.
One last note: currently BSWebTracker doesn’t do much error handling. If your website is down or otherwise cannot be reached, it’ll simply discard tracking requests and not saves them for later retry. It also doesn’t try to store the exact time when the tracking request occur and forward it to the analytics reports (e.g. backdates tracking action) and other fancy stuff. So probably the library will only be useful for online-type apps (like web browsers or instant messaging clients) and will need some adaptation to be used offline.
Get It Now
You can find
BSWebTracker in Github, under the very liberal BSD open-source license. Please let me know if you find it useful and use it in your own app.
PS: I’ll always welcome a complementary license of your app ;-)
That’s all for now. Take care!