amitdusane.com Adobe Analytics Learning

Collect the dataData Collection

Mobile SDK

Most of this module has quietly assumed a browser, and rightly so. The web is the elder sibling. Websites came first, the Yahoos and AOLs of the early internet, and Adobe Analytics was born into that world, designed around page loads and pixels. Then 2007 arrived with the iPhone and Android, and mobile apps went from novelty to everywhere. Today almost every website has a mirror app, and a growing set of experiences, ride-hailing, food delivery, mobile games, lives only in an app, because no one books a cab with a laptop balanced on their knees. The younger sibling has, in places, run well ahead of the elder. Apps are not a lesser afterthought to the web; they are equally important, and sometimes more.

Adobe did not leave that younger sibling unmeasured. It provides a mobile SDK, and the first thing to get right is the name: SDK stands for Software Development Kit, a bundle of libraries a developer builds into an app to add a capability it did not have on its own. Here, that capability is Adobe Analytics. But do not picture web tracking on a smaller screen. Inside an app the collection model turns nearly upside down. A native app is a program already installed on the device, not a document fetched fresh on each visit. There is no page load to hook, no DOM, no pixel to drop. What does not change is everything you learned earlier: eVars, props, and events still exist, the screen-view-versus-action distinction still holds, and all of it still lands in the same raw data feed. The fundamentals stay; the way you collect them flips.

It is a compiled SDK, and that has a cost

Instead of a script you drop onto a page, mobile measurement is the Adobe Experience Platform Mobile SDK, a set of libraries (a Mobile Core plus extensions like Lifecycle, Identity, Analytics, and Edge) your developers build directly into the app and ship inside the app binary through the App Store and Google Play. That shipping path creates a split worth understanding, because it is where mobile teams get caught. The SDK code itself can only change when you release a new app version and it clears store review, slow, and not fully in your control. But the configuration and rules for that SDK live in a Tags mobile property (the same tag management covered in Tag Management Systems) and update remotely at runtime with no app release at all. So what code runs is locked to your release schedule, while how it behaves can still be tuned server-side. The decoupling a tag manager buys you is still here, it just has a hard floor set by whatever SDK version is baked into the installed app.

The thing a website simply cannot do

Here is where mobile earns its own treatment rather than being an afterthought to web: lifecycle metrics. With essentially one line of setup, the Lifecycle extension automatically collects the events that define an app's existence, things a website has no concept of at all.

  • Installs, the first launch after the app is put on a device.
  • Launches, every open, with engagement and days since last use.
  • Upgrades, when a user moves to a new version.
  • Crashes and closes, plus device and app dimensions like model and app version.

A website never asks "was this an install or an upgrade," because those ideas do not exist there. For an app they are the heartbeat, which is why mobile analytics often starts here before a single custom event is written.

trackState and trackAction

For everything beyond lifecycle, mobile gives you two calls, and if you remember s.t() and s.tl() from the AppMeasurement section, these will feel familiar by design.

CallWhat it is forWeb equivalent
trackStateA screen being shown. Increments the Page Views metric.Page view, s.t()
trackActionAn action inside a screen, a tap, a download, a form step. Does not increment page views.Link/event, s.tl()

The mapping is deliberate: screens are the app's pages, actions are its interactions, so the mental model you already built carries straight over. Here is what these actually look like in an app.

Seeing it in real code

An app is built for exactly two platforms, Android and iOS, so a real implementation always exists in both. The calls are the same idea in each language. Notice the second argument every time: a small dictionary of key-value pairs. That is context data, and it is doing all the real work, a point that returns in a moment.

A page load (a screen appears). Send the page name, page type, and channel, then fire trackState:

Android (Kotlin)
val contextData = mapOf(
    "app.pageName" to "Home",
    "app.pageType" to "Landing",
    "app.channel"  to "Marketing"
)
MobileCore.trackState("Home", contextData)
iOS (Swift)
let contextData = [
    "app.pageName": "Home",
    "app.pageType": "Landing",
    "app.channel":  "Marketing"
]
MobileCore.track(state: "Home", data: contextData)

A download (a user action). Send the document name and a download flag, then fire trackAction:

Android (Kotlin)
val actionData = mapOf(
    "app.documentName" to "Pricing Guide.pdf",
    "app.download"     to "1"
)
MobileCore.trackAction("Download", actionData)
iOS (Swift)
let actionData = [
    "app.documentName": "Pricing Guide.pdf",
    "app.download":     "1"
]
MobileCore.track(action: "Download", data: actionData)

The languages differ, Kotlin and Swift, but look closely: the keys are identical across both. app.pageName, app.documentName, app.download, the same names on Android and iOS. That shared vocabulary is what makes the next step possible.

The flip: everything is context data

Here is the "upside down" moment. Notice what is missing from all that code: there is no eVar4, no prop3, no event1. From version 4 of the SDK onward, an app can no longer set Analytics variables directly at all. Everything you want to measure is sent as context data, those free-form key-value pairs, and nothing else.

Context data behaves nothing like an eVar or a prop. Think of eVars and props as the planets: fixed in number, each in its assigned orbit, bound to the Sun. Context data is the comets and asteroids, not held to any orbit, following no fixed pattern, and effectively unlimited in number. You can name a context data key anything you like and create as many as you want. That freedom is the point, but it comes with a catch: a comet is not a planet. Context data does not automatically become part of your Analytics reports or your data feed. On its own, app.documentName is just a floating label Adobe received and set aside. It has to be handed to a real Analytics variable before it means anything, and the mechanism that does the handing is Processing Rules.

Processing Rules: turning context data into variables

Processing Rules live in the report suite's Admin, and they do one job: map incoming context data onto real Analytics variables, at collection time, with no code change. You write them once in the Adobe Analytics UI, each rule a simple condition plus an action, "if this context data key is present, set that variable to its value." And here is the elegant part of your app being built twice: because the context data keys are identical on Android and iOS, you write these rules once, and they serve both platforms equally. The code is per-platform; the mapping is shared.

For the two calls above, the mapping looks like this:

From the app (context data)Processing Rule setsReports as
app.pageNamePage Namethe Pages report
app.pageTypeeVar2Page Type
app.channeleVar3Channel
app.documentNameeVar4Document Name
app.downloadevent1Downloads (a metric)

Each row is one rule. Two of them, written in the Processing Rules interface, read like this:

Do this Processing rule: Set Document Name
If
app.documentName is set
Then
Overwrite the value of eVar4 with app.documentName
Applies to
Android and iOS alike — one rule covers both
Do this Processing rule: Count a Download
If
app.download is set
Then
Set event event1
Applies to
Android and iOS alike — one rule covers both

A useful rule of thumb when you inherit an app's context data: a key whose value looks like a label (app.pageType = "Landing") usually belongs in an eVar or prop, while a key that is really just a flag (app.download = "1") usually belongs on an event. One built-in exception is worth knowing: the products string is sent directly by the SDK (via a special &&products key) and does not need a processing rule. Everything else does. The full Processing Rules toolkit, conditions, ordering, the authorization it requires, is the entire subject of Processing Rules; here you only need the shape of it.

The app sends a name, not a variable — you choose the variable afterwards
App code trackAction sends app.documentName Context data arrives at Adobe and sits inert Processing rule you map the name to eVar4 Report eVar4 = Pricing Guide.pdf shipped in the app, and frozen until the next release changeable this afternoon, in the interface Same mechanism as context data on the web, and it matters more here

Offline is the normal case, not the exception

Phones lose connectivity constantly: tunnels, elevators, planes, dead zones. A browser hit assumes a live connection; an app cannot. So the SDK queues hits on the device and sends them later, stamped with when the action actually happened rather than when it finally reached Adobe. If that sounds familiar, it should, it is exactly the timestamped-data situation from Server-Side Collection, which is why mobile data so often lives in a timestamp-enabled report suite. The timestamp decision, framed there as a server-side concern, turns out to be baked into mobile collection by its very nature.

The same two worlds, one more time

Mobile has the identical fork drawn for web. The Analytics extension sends your trackState and trackAction calls straight to Adobe Analytics, the classic path, and it is this path that relies on the context-data-plus-Processing-Rules mapping above. The Edge Network extension sends the same interactions as XDM to the very Edge Network that alloy.js feeds on the web, where a datastream maps and fans them out to Analytics, CJA, Journey Optimizer, and the rest, so the mapping moves from Processing Rules into the datastream. Same decision, same direction of travel: classic, or the Edge. One caution, running both paths at once double-counts your hits and lifecycle metrics, so it is one or the other, deliberately.

Debugging an app is its own skill

One hard truth to end on: once analytics is live in an app, it is genuinely harder to debug than a website. A browser has developer tools built in; a phone shows you nothing about the network calls leaving it. You have two good ways to see inside.

Adobe Assurance (formerly Project Griffon) is the modern, Adobe-native tool and the one to reach for first. You connect your app to a live Assurance session (by scanning a QR code or opening a deep link) and then watch every event stream out in real time, the lifecycle hits, your trackState and trackAction calls, and the exact context data on each. Its real power is that it can show you the event after Processing Rules have run, so you can confirm not just that app.documentName was sent, but that it correctly landed in eVar4. That is end-to-end validation in one screen.

A proxy debugger like Charles is the general-purpose fallback, and it works for any app, Adobe or not. The trick is to route the phone's traffic through your computer: set the phone's Wi-Fi proxy to your desktop's IP address and Charles's port, install Charles's security certificate on the device so it can read encrypted traffic, and from then on every network call the app makes appears in Charles on your desktop. Find the Analytics hit in that stream and you can inspect the raw context data keys exactly as they were sent. Assurance tells you whether the mapping worked; Charles shows you the unfiltered wire.

That is the working core of mobile collection: a compiled SDK with lifecycle metrics for free, two calls (trackState and trackAction) carrying context data, Processing Rules that turn that context data into real variables, offline-and-timestamp behavior built in, the same classic-versus-Edge choice as the rest of this module, and two ways to debug it. The deepest native territory beyond this, advertising IDs and push tokens, the full lifecycle metric reference, and the SDK installation itself, is a specialty of its own and a larger undertaking than one section can hold, but with the above you understand how app data is actually collected and shaped.

Every method in this module so far, web or app, has assumed the same thing: that somebody, somewhere, decided what data to hand over and in what shape. That decision is not made in Adobe and it is not made in your tag manager. It is made in the page itself, in an object your developers own and you do not. What Is a Data Layer is where that contract gets written.

Where to find it in Adobe

A mobile property is created under Data Collection > Tags, and it ships with a different default extension set from a web property. Datastreams for an app are wired through the Edge Network extension rather than the Web SDK one. For validating what an app actually sends, the tool is Assurance, not the browser debugger.

Need implementation steps?

This article focuses on the concepts, architecture, and practical guidance behind the topic. For the latest UI walkthroughs and step-by-step implementation instructions, use the links below. They leave this site and open Adobe's own documentation in a new tab.