Skip to main content

Tracking out-of-the-box events

To track an event, pass an event to the tracker instance.

For example, tracking a ScreenView:

let tracker = Snowplow.createTracker(namespace: "appTracker", endpoint: "")

let event = ScreenView(name: "screen name")
let eventId = tracker.track(event)

The tracker makes it easy to track different kinds of data. We provide a range of Event classes for tracking out-of-the-box event types, as well as fully custom events.

Each event has an associated context, which is composed of entities. The tracker attaches entities to the events based on the configuration, but you can attach your own custom entities as well.

Every tracked event payload has a unique event_id UUID string set by the tracker, a set of timestamps, and other ubiquitous properties such as the namespace. The event_id is returned from the tracker.track(event) method. You can know more about how events and entities are structured here.

See the full configuration and parameter options for all these classes and methods in the API docs - Android and iOS.

Auto-tracked events and entities

Automatically captured data are:

Autotracking can be enabled in the tracker configuration. In this example, some helpful automatic entities and all autotracking is enabled:

Snowplow.createTracker(namespace: "appTracker", network: networkConfig) {

You can also configure your tracker to automatically add GDPR information to every event.

Manually-tracked events

The tracker provides classes for tracking different types of events. The events are divided into two groups: canonical events and self-describing events.

Creating a Structured event

Our philosophy in creating Snowplow is that users should design suitable data structures customised for their own consumer interactions data capture. You can read more about that philosophy here.

However, as part of a Snowplow implementation there may be interactions where custom Self Describing events are perhaps too complex or unwarranted. They are then candidates to track using Structured, if none of the other event-specific methods outlined below are appropriate.

let event = Structured(category: "Example", action: "my-action")


Creating a Timing event

Use the Timing events to track user timing events such as how long resources take to load.

let event = Timing(category: "timing-category", variable: "timing-variable", timing: 5)


Creating a ScreenView event

Track the user viewing a screen within the application. This type of tracking is typically used when automatic screen view tracking is not suitable within your application.

let event = ScreenView(name: "DemoScreenName", screenId: UUID())


Use the ConsentGranted event to track a user opting into data collection. A consent document context will be attached to the event using the id and version arguments supplied.

let event = ConsentGranted(expiry: "2022-01-01T00:00:00Z", documentId: "1234abcd", version: "1.2")       


Use the ConsentWithdrawn event to track a user withdrawing consent for data collection. A consent document context will be attached to the event using the id and version arguments supplied. To specify that a user opts out of all data collection, all should be set to true.

let event = ConsentWithdrawn()


Tracking Ecommerce Transactions

Modelled on Google Analytics ecommerce tracking capability, Snowplow uses three steps that can be used together to track online transactions:

  1. Create a Ecommerce event. Use Ecommerce to initialize a transaction object. This will be the object that is loaded with all the data relevant to the specific transaction that is being tracked including all the items in the order, the prices of the items, the price of shipping and the order_id.

  2. Add items to the transaction. Create an array of EcommerceItem to pass to the Ecommerce object.

  3. Submit the transaction to Snowplow using the track() method, once all the relevant data has been loaded into the object.

let transactionID = "6a8078be"       

let itemArray = [
EcommerceItem(sku: "DemoItemSku", price: 0.75, quantity: 1)

let event = Ecommerce(orderId: transactionID, totalValue: 350, items: itemArray)


Tracking Push and Local Notifications

To track an event when a push (or local) notification is used, it is possible to use the MessageNotification event:

let event = MessageNotification(title: "title", body: "body", trigger: .push)
.bodyLocKey("loc key")
.bodyLocArgs(["loc arg1", "loc arg2"])
MessageNotificationAttachment(identifier: "id", type: "type", url: "")

The Deep Link is received by the mobile operating system and passed to the related app. Our mobile tracker can't automatically track the Deep Link, but we provide an out-of-the-box event that can be used by the developer to manually track it as soon as the Deep Link is received in the app.

It will be the duty of the tracker to automatically attach the information of the Deep Link to the first ScreenView tracked.

In practice, when the app receives a Deep Link, the developer can track it through the DeepLinkReceived event:

public func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([Any]?) -> Void) -> Bool
if let url = userActivity.webpageURL {
let deepLinkEvent = DeepLinkReceived(url: userActivity.webpageURL.absoluteString)

The tracker keeps memory of the tracked Deep Link event and will attach a Deep Link entity to the first ScreenView tracked in the tracker. This is helpful during the analysis of the data because it will be clear the relation between the content visualized by the user (ScreenView event) and source (DeepLink entity) that originated that visualisation.

This behavior is enabled by default but it can be disabled from the TrackerConfiguration.

For example:

let trackerConfig = TrackerConfiguration()

The DeepLinkReceived event can be used in pair with a campaign-attribution-enrichment appropriately enabled in the Snowplow pipeline. It works exactly like for PageView events in the web/JS tracker. When the user taps on an advertising banner or a marketing email or message, it can trigger the launch of the app through the Deep Linking feature. The referral from the advertising campaigns, websites, or other source can be composed by UTM parameters used to attribute the user activity back to the campaign. The Campaign Attribution Enrichment can parse the DeepLinkReceived event extracting the UTM parameters in the deep link url.

The tracked DeepLinkReceived event and each subsequent ScreenView event also have the URL and referrer information added in the page_url and page_referrer atomic properties. This makes them compatible with data models and enrichments built for events tracked on the Web.

Tracking data that is not event-type specific

Some data, such as that relating to the user whose activity is being tracked, is relevant across all event types. The tracker provides two mechanisms for tracking this kind of data.

Certain properties, including userId or ipAddress, can be set as "atomic" properties in the raw event, using the Subject class.

A more general and powerful method is to attach self-describing JSON "context entities" to your events - the same JSON schemas as used for self-describing events. This means that any data that can be described by a JSON schema can be added to any or all of your events. Read more on the next page.

All events also provide the option for setting a custom timestamp, called trueTimestamp. See below for details.

Adding custom timestamps to events

Snowplow events have several timestamps. The raw event payload always contains a deviceCreatedTimestamp (dtm) and a deviceSentTimestamp (stm). Other timestamps are added as the event moves through the pipeline.

Every Event in the tracker allows for a custom timestamp, called trueTimestamp to be set. Read more about timestamps in this still relevant forums post.

A trueTimestamp can be added to any event using the trueTimestamp() method:

// This example shows a self-describing event, but all events can have a trueTimestamp
let event = SelfDescribing(schema: "iglu:com.snowplowanalytics.snowplow/link_click/jsonschema/1-0-1", payload: data)
.trueTimestamp(Date(timeIntervalSince1970: 166184300))

trueTimestamp should be a Date object.

Was this page helpful?