This document describes how to sync a session in a hybrid app. A hybrid app combines components written in native code, such as Objective-C for iOS or Java for Android, and one or more WebView components written in HTML and JavaScript. A common use case is a shopping app where a native code component is used for browsing products and a WebView component is used for the checkout and payment processing.

Table of Contents Placeholder

The Problem

A common challenge for analytics vendors on hybrid apps is being able to track a session between the native component and the WebView component. Even if the vendor is integrated into both components a visitor will be assigned a separate session identifier in each, and the vendor's reports will show inflated numbers for sessions.

The Solution

To solve this problem we need a way for the native and WebView components to share information. This is accomplished by appending a query string parameter to the WebView URL loaded by the native code. This parameter will contain the shared session ID that will be used in both the native and WebView components.

The initiation and sharing of that session ID will be done in your Tealium iQ configuration and with some custom code in your native app. The Custom Remote Command tag (formerly TagBridge) will facilitate the sharing of that session ID between Tealium's hidden WebView and the native code, where it can then be passed along to your website that loads from a visible WebView.

Requirements

Here are the requirements for this solution:

Native Code Requirements

The following components are required in the native app:

  • Custom Remote Command - a custom command defined in the native code to be called by the Custom Remote Command tag. This allows Tealium to pass data from the hidden WebView to the native code.
  • WebView Query String Parameter - a query string parameter containing the session ID will be appended to the URL that loads the WebView component of your hybrid app.

iQ Mobile Profile Requirements

The iQ profile that manages your native app will need the following required changes:

  • Custom Remote Command Tag - a tag that facilitates communication between the hidden WebView and the native app code.
  • session_id - a UDO Variable used to store the vendor session ID that is passed by the Custom Remote Command tag to the native code.
  • JavaScript Code Extension - custom JavaScript to fetch the current session ID from the vendor and pass it to the Custom Remote Command tag.

iQ Mobile Site Profile Requirements

The following customization are required in the iQ profile for the WebView component of your hybrid app:

  • session_id - a Query String Variable used in the URL of the WebView to pass the session ID from the native code.
  • Custom Code - a small snippet of code JavaScript code (extension or tag template) to facilitate passing the session ID to the vendor tag.

Here is a summary of the requirements and where they live within the hybrid app:

Hybrid App
Native Code
Component
Native code loads WebView at URL with:
&session_id=SESSION

 

WebView
Component
iQ Mobile Profile
(run in hidden WebView)
Native Code iQ Profile for Website
  • Configure Custom Remote Command syncSessionId command
  • JavaScript Code Extension to get session ID from vendor
  • Call to utag.link() to trigger Custom Remote Command, passing session ID
  • Custom code to handle remote calls to syncSessionId
  • Custom code to pass session ID variable to the WebView
  • Query string variable session_id from the WebView URL
  • Vendor Tag with data mapping for session_id

We will demonstrate this solution using Google Analytics, but it applies to any vendor that supports session management. For the Google Analytics example we will retrieve a session ID (clientId) in the Tealium iQ SDK (generated in a hidden WebView and passed to the native code via a remote command), pass it to the WebView component of a hybrid app via a query string parameter, then use Tealium iQ to pass the session ID back to Google Analytics running on the website inside the WebView. This example will focus mainly on Android, but the process for iOS is exactly the same.

Assumptions and Prerequisites

  • This article assumes that you are using Tealium for Android/iOS v5.0+
  • This method requires changes to the source code of your app, and thus, a redeployment to the App Store/Play Store.

Implementation

Add a Remote Command (Native Code)

Use the addRemoteCommand method to define a new command for the Custom Remote Command tag to utilize. This allows the hidden Tealium WebView to pass data to the Tealium library in the native code environment.

Android (Java code):

Although fully functional, this code is simply a mockup to show how to accomplish this task. Use your own judgment, and always test before deploying code in your live app


1. Define a new remote command called syncSessionId that stores the passed session ID value into a native variable called sessionId. Place this code in the Tealium init block (often this will be in a helper file):

// initialize Tealium
Tealium.Config config = Tealium.Config.create(application, "", "", "");
// create a new Tealium instance with the above config object
Tealium inst = Tealium.createInstance(TEALIUM_INSTANCENAME, config);
// register a new RemoteCommand with Tealium called "syncGASession"
inst.addRemoteCommand(new RemoteCommand("syncSessionId", "Syncs the Analytics Session ID") {
    // onInvoke will be called when Tealium iQ triggers the command
    @Override
    protected void onInvoke(Response response) throws Exception {
        // grab the response object
        JSONObject resp = response.getRequestPayload();
        // set the application-level "gaSessionId" String variable to the value of the key "sessionId" in the response
        // assumes you created this shared variable in your Application class. See sample app for details.
        DemoApplication.sessionId = resp.optString("sessionId", null);
    }
});

2. Customize your WebView to append the query string parameter session_id with the session value stored in the native code. Here's an example of a WebView being created and the session ID being passed as a query string parameter:

public class WebviewActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_webview);
        webview myWebView = (webview) findViewById(R.id.webview);
        myWebView.clearCache(true);
        myWebView.getSettings().setJavaScriptEnabled(true);
        myWebView.loadUrl("https://solutions.tealium.net/hosted/cpr/mobile_ga_demo.html?session_id=" + DemoApplication.sessionId);
    }
}

iOS (Objective-C code)

Here's a fragment of the equivalent Objective-C code required to achieve the same thing on iOS. This code does not include the creation of the webview and is included as a starting point:

// replace with your instance name
Tealium *instanceHandle = [Tealium instanceForKey: @"tealium"]; 
[instanceHandle addRemoteCommandID:@"syncSessionId"
   description:@"Syncs the Session ID"
   targetQueue:dispatch_get_main_queue()
 // response is generated from the mappings set up in Tealium iQ
   responseBlock:^(TEALRemoteCommandResponse * _Nonnull response) {
 // grab the Session ID from the response object
       NSString *session_id = response.requestPayload[@"sessionId"];
 /* now that you have the session ID, store it somewhere you can 
 access it later on when you create your webview. See Android code
 for an example */
}];

Add the Custom Remote Command Tag (iQ Profile for Mobile)

In your iQ Mobile Profile, you will use the Custom Remote Command tag to trigger the remote command you defined in your native code. By adding data mappings to this tag, the remote command will receive data.

Follow these steps in your mobile profile:

  1. Add the following variables to your Data Layer:session_id (type = "UDO Variable")
  2. Add the Custom Remote Command tag from the Tag Marketplace:
    Custom Remote Command Tag.jpg
  3. Set the Command ID to "syncSessionId" (the same name as the remote command defined in the native code):
    Custom Remote Comman_syncSessionId.jpg
  4. Add a data mapping for session_id (UDO Variable) to "sessionId":
    tagbridge-mapping-sessionid.jpg

Add the Vendor Tag (iQ Profile for Mobile)

In your iQ Mobile Profile, you will use a vendor tag (Google Analytics in this example) to initiate a session and pass the session ID value to the Custom Remote Command tag using a call to utag.link(). Most likely you will already have this tag added to your mobile profile for the purpose of native app tracking (as many popular analytics tag are mobile enabled).

Follow these steps to add and configure your vendor tag:

  1. Add your vendor tag (if you haven't already).
  2. Add a JavaScript Code Extension scoped to the vendor tag (Google Analytics) with the following contents:

    You will need the UID of the Custom Remote Command tag for this step.

  3.  window.setTimeout(function() {
    // Vendor Specific: Retrieve a session ID from Google Analytics
    var tracker = window.ga.getByName('tealium_0'); // assumes you only have 1 GA tracker on the page
    var clientId = tracker.get('clientId');
    // A tracking call picked up Custom Remote Command
    utag.link({session_id : clientId}, null, ['<UID FROM CUSTOM REMOTE COMMAND TAG>'])
    }, 1000);
    This extension waits for 1 second to give the tag enough time to load, and then grabs the session ID from the vendor. It then calls utag.link() explicitly for the Custom Remote Command tag, passing session_id as a parameter. The Custom Remote Command tag then passes that data to the remote command syncSessionId where the native code will stored it for later use.

Add the Vendor Tag (iQ Profile for Web)

In your iQ Web Profile (the profile used for the website that is loaded in the WebView component of your hybrid app) you will define a new Data Layer variable to detect the query string parameter used for the session ID and map that variable into the vendor tag.

Follow these steps to configure your vendor tag to sync the session ID:

  1. Add your vendor tag, if you haven't already.
  2. Add a new Data Layer variable named session_id of type Querystring Parameter.
  3. In the vendor tag, add a data mapping for session_id to "clientId" (specific to Google Analytics in this example)

You're now finished. Assuming you've followed all the steps above, the WebView(s) in your app will receive the same GA session identifier as the native app, and your users will now be using a single session (as far as Google Analytics is concerned).

Validating the Results

After deploying the code above, you can use a local proxy, such as Charles Proxy or Fiddler, to view the output from the app. Check the outgoing hits to www.google-analytics.com and you will see that the cid parameter is the same in the hit coming from your native app as from the WebView component.

Learn more about debugging mobile implementations.

Testing from native app:

testing_1.png

Testing from in-app WebView:

testing_2.png

If you wish to inspect or test the sample app, you can download it here. Please note this is a zipped-up Android Studio project.

Vendor Solutions

This guide describes how to sync the session IDs for Google Analytics, but the same steps can easily be adapted for use with other vendors, such as Webtrends, Webtrekk, and Adobe Analytics to name a few. Depending on the product in question, you may need to read cookie values directly if there is no API available to grab the session information. This method could also be used to pass other information back to your app, outside of the scope of your analytics tools. It is possible to pass more than 1 parameter at a time by adding more mappings in the Custom Remote Command tag, but you will need to adapt the native RemoteCommand code to handle additional parameters in the response object.

Related articles:

Attachments
Public