Hybrid Apps: Making Whole Two Halves

white iphone
Whether you know it or not, you likely have used a hybrid app on a smartphone or tablet. Hybrid apps often appear like “regular” apps, however some of the content displayed within the app is HTML web content. So in essence it’s like having a dedicated mobile web browser “live” within the app. These types of apps are popular especially for retail, transportation, and banking industry verticals. For example, the mobile app for a popular big box retailer leads customers through a native app experience initially when discovering and selecting products to purchase; however, when checking out, the content displayed within the app is web generated. From an analytic perspective there are tracking solutions to measure both mobile app and mobile web, each with its own means of uniquely identifying users. Therefore, if unaddressed, a single customer visit within a hybrid app will appear as two visits, two visitors, and the potential of crazy wormhole pathing behavior. Within this blog post I describe how to synchronize visitor IDs within a hybrid app which yields more accurate mobile metrics.

Visitor IDs within Apps
Adobe’s Mobile App Libraries (available for iOS, Android, WP8) generate their own random unique visitor ID when an app is installed. This visitor ID is stored within persistent memory on the mobile device and is submitted as a “vid” value on every hit. Unlike cookies this visitor ID will always be set and can’t be erased unless the user uninstalls the app (app visitor IDs will persist through upgrades).

Visitor IDs within Mobile Web
Currently, most mobile web implementations use the same standard s_code that is used within desktop sites. As such, Adobe Analytics creates an s_vi cookie that uniquely identifies visitors on a given site. Adobe’s servers will use the s_vi cookie value that is passed within the header unless the s.visitorID (vid) name and value is passed along with the other props, eVars or events that are normally submitted.

Bringing the two together
In order to have both halves of the hybrid app experience be considered one visitor and one visit, the visitor ID used within the app must also be used within mobile web. To do this we must place the following code within the app code and mobile web s_code.

App Visitor ID Hand-off Code

ADMS_Measurement *measure = [ADMS_Measurement sharedInstance];
[measure configureMeasurementWithReportSuiteIDs:@”your_report_suite_id” trackingServer:@”your_tracking_server.112.2o7.net”];

NSString *visitorId = measure.visitorID;

NSString * urlString = [NSString stringWithFormat:@”http://www.mydomain.com/index.php?appvi=%@”, visitorId];

NSURL *url = [NSURL URLWithString:urlString];
[[UIApplication sharedApplication] openURL:url];

The Objective-C (iOS) code above reads the app visitor ID and places it within the “appvi” query parameter within the URL. For simplicity and brevity the code then opens the URL within the Safari mobile browser and does not leverage the UIWebView as would normally be done. Please adapt accordingly.

NOTE: The visitorId shown above is populated using measure.visitorID found with the iOS AppMeasurement Library that will be released on March 22, 2013. If you need the alternative method to populate the visitorId with older 3.x libraries, please let me know in the comment section below.

Mobile Web Visitor ID Pick-Up Code

if (s.getQueryParam(‘appvi’)) {
s.new_vi_date=new Date;
s.new_vi_date.setFullYear(s.new_vi_date.getFullYear() + 5);

else if (s.c_r(‘app_vi’)) {

Within the s_code javascript, place the above code within s_doPlugins(). Initially this grabs the app visitorID handed over from the app, stores that value into a five-year cookie, and will use that value moving forward within the app whether the app visitorID is present within the URL or not. This code also relies on the getQueryParam plug-in. If you don’t have the plug-in, ask your Adobe Consultant to provide it to you. Or, you can easily find on the web an equivalent javascript function that retrieves query parameters from a URL.

Finally, to validate be sure your app visitorID (again, shown as “vid”) is also present within mobile web. It should be included on every mobile web hit. Once you have verified that the same visitor ID is being shared between app and mobile web, you can rest assured that you can now capture the whole journey of your hybrid app visitors.

Update 8-25-2014:

Since this blog post was published before the 4.x SDK was released, here is an update to the code segments above that adjust for how visitor IDs are generated within the 4.x SDK.

Additional method (to be used with the 4.x SDK) that retrieves the correct visitorID (Android would be very similar).

// The value returned from this method should be set to the visitor ID parameter that is placed within the URL

+ (NSString *)retrieveVisitorIdentification {

//Check to see if vid is set, if so grab and return.
if ([ADBMobile userIdentifier]) {
return [ADBMobile userIdentifier];

//If not set, get aid and return.
else {
return [ADBMobile trackingIdentifier];

Furthermore, adjust this code segment as shown (see bold areas, in particular).

From this…

NSString *vis­i­torId = measure.visitorID;

NSString * url­String = [NSString stringWithFormat:@“http://www.​mydomain.com/index.php?appvi=%​@”, visitorId];

NSURL *url = [NSURL URLWithString:urlString];
[[UIAp­pli­ca­tion sharedAp­pli­ca­tion] openURL:url];

To this….

NSString * urlString = [NSString stringWithFormat:@”http://www.​mydomain.com/index.php?appvi=%​@“, **[TrackingHelper retrieveVisitorIdentification]**​];

NSURL *url = [NSURL URLWithString:urlString];
[[UIApplication sharedApplication] openURL:url];