I love mobile apps. They are my nearly constant companions. At lunch, I can get caught up on the news I missed during the morning. On the drive home from work, I get streaming music from all over the world (and, during the summer, the live Red Sox radio feed I desperately crave). And after work, I can tweet and e-mail as needed from wherever my family and I end up.

Ever since the iPhone App Store launched in July 2008, it seems that the battle for the growing smartphone market has centered largely on apps. As Apple and competitors release improved operating systems and distribution layers, organizations—likely including yours and those in your industry—will be quick to develop applications to run on them. In this crowded world, measuring usage of your application is key to the success.

With the new webOS by Palm, it is easier than ever to implement application measurement, so measuring user interaction is really straightforward. In fact, my colleague, Jeff Minich, posted on this very topic last week and discussed some of the awesome things you can do with Palm Pre app measurement, so I thought I’d tackle the implementation side of the topic here. App development for webOS is done in JavaScript; technically, you could even use the standard SiteCatalyst JavaScript library, just as you probably do on your site, but here are some best practices suggested and co-authored by Dennis Wilkins, a member of the Omniture Engineering team with significant experience building mobile apps.

The first thing you want to do in setting up measurement of your Palm Pre app is download the core SiteCatalyst JavaScript code from the Code Manager in the Admin Console. (Since mobile apps are not the same as your web site, we recommend creating a new report suite in the Admin Console specifically for measuring each mobile app.)

Create a folder in your project called “lib” and save that core tracking code in there. I named my file s_code.js. Next in the sources.json file, in your project add this line of code to the array of sources.

{"source": "lib\/s_code.js"},

Now that you’ve done that, the s_code library can be called anywhere in the application. For simplicity, in this appinfo.json file in our project, we’ve added to the object a variable called “reportSuite:”

{
"id": "com.omniture.tracking",
"version": "1.0.0",
"vendor": "Omniture",
"type": "web",
"main": "index.html",
"title": "tracking",
"icon": "icon.png",
"reportSuite": "omniture.test"
}

You can also add any additional static information inside that file.

Now, in the app/assistants/stage-assistant.js file, we’ll add some sample code to send a page view and instantiate a visit every time the application is launched (stage-assistant.js will only be run once in basic webOS applications, and only when the application is launched):

StageAssistant.prototype.sendTrackingCode = function()
{
var s_account = Mojo.Controller.appInfo.reportSuite; // grab the report suite out of the appinfo.json file
var s=s_gi(s_account);
s.pageName = "Application Launch"; // you could put any name here
s.channel = Mojo.Controller.appInfo.id; // add the application id (optional)
s.prop1 = "X"; // set a prop if you want to
s.t(); // send tracking code, and voila! you're done
}

Now in the StageAssistant setup function, we tell it to execute that code:

StageAssistant.prototype.setup = function()
{
this.sendTrackingCode(); // do this first
this.controller.pushScene('first'); // push our first scene, or do any other logic as necessary
}

And that is how you could begin a simple implementation for the Palm Pre’s webOS. Not too tough, eh? Note that any other SiteCatalyst variables can be set within the sendTrackingCode() function, as necessary.

More advanced app measurement isn’t much more difficult. Here is some sample code from our first scene. As you examine this example, take none of the NDUID value; this ID is perfect as a SiteCatalyst visitor ID, since it represents the unique ID of the specific Palm Pre running the app. It will always be unique, and will never change, so it allows us to measure how many time a specific user has loaded the app or done a specific action within the app. Below, we are also are setting the pageName to the user’s current scene; you may want to append the application name or something else to the page name to better identify it came from that app, if you are sharing the report suite with your web site or another application. (Again, sharing a report suite with your web site or even other mobile apps is not typically recommended. Circumstances may vary.)

FirstAssistant = Class.create({
user: false,

initialize: function(user)
{
this.user = user || {}; // assume I was passing around a user object to the scene when it was created. if it wasn't passed make it a blank object
},

setup: function()
{
this.startTrackingCodeChain(); // only fire tracking code when scene is created
},

activate: function(e)
{
// fire tracking code when the scene is activated, meaning that if a scene is pushed on 'this' and someone goes back it, will be fired a second time
//this.getUniqueIDThenSendTrackingCode();
},

deactivate: function(e)
{

},

cleanup: function(e)
{

},

// the reason why we are doing a tracking code chain is because the unique ID is obtained asynchronously
startTrackingCodeChain: function()
{
var nduid = Mojo.Model.Cookie('nduid'); // we could already have it, so store it
var uniqueID = nduid.get();
if (uniqueID) // if we do have it, fire the tracking code off with it; if we don't have it, do the asynch request to get it.
{
this.doTracking(uniqueID);
}
else
{
// this should only happen once per install, the cookie will remain as long as they have it installed
this.controller.serviceRequest('palm://com.palm.preferences/systemProperties', {
method:"Get",
parameters:{"key": "com.palm.properties.nduid" },
onSuccess: this.setUniqueID.bind(this) // here is the call back to do
}
});
}
},

setUniqueID: function(uniqueID)
{
var nduid = Mojo.Model.Cookie('nduid'); // once we have it, let's store it in the cookie so we don't have to get it ever again. . .
nduid.put(uniqueID); // storing the ID. . .
this.doTracking(uniqueID); // now send tracking code, finishing the chain
},

doTracking: function(uniqueID)
{
var s_account = Mojo.Controller.appInfo.reportSuite; // get the report suite our of appinfo.json
var s=s_gi(s_account);
s.pageName = this.controller.sceneName; //set the page name to the current scene's name (in this case its 'first')
s.visitorID = uniqueID; // use the devices id as visitorID.
s.prop1 = this.user.user_name || "Not logged in"; // we assumed the user object was passed in, so get the username, or, if it is false (or undefined), make it "not logged in"
s.t(); // fire tracking code
}
});

Of course, your app will have unique data points that you will want to measure; this code is provided as a basic example, but any data about your users or their experience that your app makes available to you is free game for collection in SiteCatalyst; all you will need to do is set SiteCatalyst variables, likely the s.events variable, Custom Traffic (s.prop) variables, or Custom Conversion (eVar) variables to whatever variables in your app contain the data points you wish to track.

Questions? Concerns? Applause? Please feel free to contact me by leaving a comment on this post, or via Twitter or FriendFeed. I’d love to hear from you!

2 comments
Andreas
Andreas

Nice article Ben! Could you point me to the location of the s_account information? I have the report suite name, but I don't receive data and I am not sure if I have the fully qualified name. Thanks for any insight.

Ben Gaines
Ben Gaines

Sure! If you have access to the account's Admin Console (in SiteCatalyst), you can get the s_account information by going to Admin > Report Suites. You'll see a column called "Report Suite ID." That's the exact value that should go in s_account. If you don't have access to the Admin Console, you'll probably want to talk to one of your admins to get this value. It needs to entered exactly in order for SiteCatalyst to capture data from your WebOS app. Good luck! Let me know if you run into any trouble or confusion from here.