# How to Migrate from Snowplow to RudderStack

<p>This document covers the steps required to migrate from <a href="https://snowplow.io/" >Snowplow</a> to RudderStack and replace your instrumentation code. You can then start using the RudderStack SDKs to track your events with minimal code changes.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="set-up-your-rudderstack-dashboard">Set up your RudderStack dashboard</h2><ol>
<li><a href="https://app.rudderstack.com/signup" >Sign up</a> for RudderStack.</li>
<li>Set up the source-destination connections in the dashboard to facilitate event data flow. For more information on setting up connections, see the <a href="https://www.rudderstack.com/docs/data-pipelines/event-stream/quickstart/" >Quickstart</a> guide.</li>
</ol>

<blockquote class="success">
  <div class="tip-quote">
    
    <div class="tip-text">
      Note your <a class='glossary-tooltip' href='/docs/get-started/introduction/glossary/#write-key'>source write keyThe write key (or source write key) is a unique identifier for your source. RudderStack uses this key to send events from a source to the specified destination.
</a> and <a class='glossary-tooltip' href='/docs/get-started/introduction/glossary/#data-plane-url'>data plane URLThe data plane URL is the location where events are routed and sent to the RudderStack backend for processing. You can find this URL at the top of the Connections page in your RudderStack dashboard.
</a> as they will be used in the next section.
    </div>
  </div>
</blockquote>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="update-your-sdk-implementation">Update your SDK implementation</h2><p>Depending on your target platform, follow these steps to move your existing Snowplow SDK implementation to RudderStack.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="android-java--legacy">Android (Java) — Legacy</h3><p>RudderStack distributes the Rudder Snowplow adapter SDK through <a href="https://central.sonatype.com/artifact/com.rudderstack.android.snowplow/adapter/1.0.0.beta.1" >Maven Central</a>. We recommended you add the SDK to your project through the Android Gradle build system.</p>
<ol>
<li>Add the following code in your project level <code>app/build.gradle</code> file:</li>
</ol>
<div class="rs-code">
  <div class="rs-code__head">groovy<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-groovy" data-lang="groovy">buildscript {
  repositories {
    mavenCentral()
  }
}
allprojects {
  repositories {
    mavenCentral()
  }
}</code></pre></div>
</div>
<ol start="2">
<li>Add the following dependency under <code>dependencies</code> section in your <code>app/build.gradle</code> file:</li>
</ol>
<div class="rs-code">
  <div class="rs-code__head">groovy<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-groovy" data-lang="groovy">implementation &#39;com.rudderstack.android.snowplow:adapter:1.0.0.beta.1&#39;</code></pre></div>
</div>
<ol start="3">
<li>Update your SDK initialization to any one of the following snippet (method 1, 2, or 3 in the following snippets). Also, replace the <code>WRITE_KEY</code> and <code>DATA_PLANE_URL</code> with your source write key and data plane URL obtained in the above section.</li>
</ol>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-dabcef"
		
		>Java</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-cabdef"
		
		>Kotlin</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-dabcef">

<div class="rs-code">
  <div class="rs-code__head">java<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java">//Method 1: Default values are considered for all configuration objects 
//except networkConfiguration.
RSTracker tracker = new RSTracker()
            .createTracker(
                this, WRITE_KEY, networkConfiguration
            );

//Method 2: Default values are considered for all configuration objects.
RSTracker tracker = new RSTracker()
            .createTracker(
                this, WRITE_KEY, DATA_PLANE_URL
            );

//Method 3: Values for all configuration objects must be provided.
RSTracker tracker = new RSTracker()
            .createTracker(
                this, WRITE_KEY, networkConfiguration,
                sessionConfiguration, trackerConfiguration,
                subjectConfiguration
            );</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-cabdef" hidden>

<div class="rs-code">
  <div class="rs-code__head">kotlin<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-kotlin" data-lang="kotlin">//Method 1: Default values are considered for all configuration objects 
//except networkConfiguration.
val tracker = RSTracker()
            .createTracker(
                this, WRITE_KEY, networkConfiguration
            )

//Method 2: Default values are considered for all configuration objects.
val tracker = RSTracker()
            .createTracker(
                this, WRITE_KEY, DATA_PLANE_URL
            )

//Method 3: Values for all configuration objects must be provided.
val tracker = RSTracker()
            .createTracker(
                this, WRITE_KEY, networkConfiguration,
                sessionConfiguration, trackerConfiguration,
                subjectConfiguration
            )</code></pre></div>
</div>

</div>

</div>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">Refer to the <a href="#setting-configuration-objects" >Setting the configuration objects</a> section for more information on using these configuration objects.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="ios-obj-c--legacy">iOS (Obj-C) — Legacy</h3><p>Follow these steps to migrate to the RudderStack iOS (Obj-C) SDK:</p>
<ol>
<li>Add the SDK to your <code>Podfile</code>:</li>
</ol>
<div class="rs-code">
  <div class="rs-code__head">ruby<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-ruby" data-lang="ruby">pod &#39;RudderSnowplowMigrator&#39;, &#39;1.0.0.beta.1&#39;</code></pre></div>
</div>
<ol start="2">
<li>Run the following command:</li>
</ol>
<div class="rs-code">
  <div class="rs-code__head">ruby<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-ruby" data-lang="ruby">pod install</code></pre></div>
</div>
<ol start="3">
<li>Add the following code in all <code>.m</code> and <code>.h</code> files (for Objective-C) or <code>.swift</code> files(for Swift) where you want to refer or use RudderStack SDK classes:</li>
</ol>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-edbcaf"
		
		>Objective-C</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-ecfadb"
		
		>Swift</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-edbcaf">

<div class="rs-code">
  <div class="rs-code__head">objectivec<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-objectivec" data-lang="objectivec">@import RudderSnowplowMigrator;</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-ecfadb" hidden>

<div class="rs-code">
  <div class="rs-code__head">swift<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift">import RudderSnowplowMigrator</code></pre></div>
</div>

</div>

</div>

<ol start="4">
<li>Update your SDK initialization to any one of the following snippet (method 1, 2, or 3). Also, replace the <code>WRITE_KEY</code> and <code>DATA_PLANE_URL</code> with your source write key and data plane URL obtained in the above section.</li>
</ol>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-deacbf"
		
		>Objective-C</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-dfceab"
		
		>Swift</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-deacbf">

<div class="rs-code">
  <div class="rs-code__head">objectivec<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-objectivec" data-lang="objectivec">//Method 1: Default values are considered for all configuration objects 
//except networkConfiguration.
RSTracker *tracker = [RSTracker createTrackerWithWriteKey:WRITE_KEY network:networkConfig];

//Method 2: Default values are considered for all configuration objects.
RSTracker *tracker = [RSTracker createTrackerWithWriteKey:WRITE_KEY dataPlaneUrl:DATA_PLANE_URL];

//Method 3: Values for all configuration objects must be provided.
RSTracker *tracker = [RSTracker createTrackerWithWriteKey:WRITE_KEY network:networkConfig configurations:@[trackerConfig]];</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-dfceab" hidden>

<div class="rs-code">
  <div class="rs-code__head">swift<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift">//Method 1: Default values are considered for all configuration objects 
//except networkConfiguration.
let tracker = RSTracker.createTracker(
            writeKey: WRITE_KEY,
            network: networkConfig
        )

//Method 2: Default values are considered for all configuration objects.
let tracker = RSTracker.createTracker(
            writeKey: WRITE_KEY,
            dataPlaneUrl: DATA_PLANE_URL
        )

//Method 3: Values for all configuration objects must be provided.
let tracker = RSTracker.createTracker(
            writeKey: WRITE_KEY,
            network: networkConfig,
            configurations: [trackerConfig, sessionConfig]
        )</code></pre></div>
</div>

</div>

</div>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">Refer to the the <a href="#setting-configuration-objects" >Setting the configuration objects</a> section for more information on using these configuration objects.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="javascript">JavaScript</h3><p>To migrate to the RudderStack JavaScript SDK, add the following code snippet in the <code>&lt;head&gt;</code> section of your website. Also, replace the <code>WRITE_KEY</code> and <code>DATA_PLANE_URL</code> with your source write key and data plane URL obtained in the above section.</p>
<div class="rs-code">
  <div class="rs-code__head">html<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-html" data-lang="html">&lt;script&gt;
  rs=window.rs=[],rs.snoplowAdapter=function(){rs.push(Array.prototype.slice.call(arguments))},rs.snoplowAdapter(&#34;newTracker&#34;,&lt;WRITE_KEY&gt;,&lt;DATA_PLANE_URL&gt;,{&lt;Configurations&gt;});
  //Optionally, use RudderStack JavaScript SDK load options
  rudderanalytics.load();
&lt;/script&gt;

&lt;script src=&#34;https://cdn.rudderlabs.com/adapter/sp/beta/v1/rs-sp-analytics.min.js&#34;&gt;&lt;/script&gt;</code></pre></div>
</div>
<p>The <code>&lt;Configurations&gt;</code> parameter in the above snippet can be replaced by the following Snowplow properties which are mapped to the RudderStack properties as shown:</p>
<table>
  <thead>
      <tr>
          <th>Snowplow property</th>
          <th>RudderStack property</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>cookieDomain</code></td>
          <td><code>setCookieDomain</code></td>
      </tr>
      <tr>
          <td><code>cookieSameSite</code></td>
          <td><code>sameSiteCookie</code></td>
      </tr>
      <tr>
          <td><code>cookieSecure</code></td>
          <td><code>secureCookie</code></td>
      </tr>
  </tbody>
</table>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="setting-configuration-objects">Update mobile SDK configuration</h2><p>RudderStack supports setting values for the following Snowplow configuration objects in the mobile SDKs (iOS (Obj-C)/Android (Java)). If not set, the default values are assigned.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="networkconfiguration">NetworkConfiguration</h3><p>The <a href="https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/mobile-trackers/configuring-how-events-are-sent/" ><code>NetworkConfiguration</code></a> class can be used to specify the collector endpoint:</p>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-afcdbe"
		
		>Objective-C</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-cdbafe"
		
		>Swift</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-efcdba"
		
		>Java</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-dabefc"
		
		>Kotlin</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-afcdbe">

<div class="rs-code">
  <div class="rs-code__head">objectivec<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-objectivec" data-lang="objectivec">// 1
RSNetworkConfiguration *networkConfig = [[RSNetworkConfiguration alloc] initWithDataPlaneUrl:DATA_PLANE_URL];
// 2
RSNetworkConfiguration *networkConfig = [[RSNetworkConfiguration alloc] initWithDataPlaneUrl:DATA_PLANE_URL controlPlaneUrl:CONTROL_PLANE_URL];</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-cdbafe" hidden>

<div class="rs-code">
  <div class="rs-code__head">swift<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift">// 1
let networkConfig = NetworkConfiguration(dataPlaneUrl: DATA_PLANE_URL)
// 2
let networkConfig = NetworkConfiguration(dataPlaneUrl: DATA_PLANE_URL, controlPlaneUrl: CONTROL_PLANE_URL)</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-efcdba" hidden>

<div class="rs-code">
  <div class="rs-code__head">java<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java">// 1
NetworkConfiguration networkConfiguration = new NetworkConfiguration(DATA_PLANE_URL);
// 2
NetworkConfiguration networkConfiguration = new NetworkConfiguration(DATA_PLANE_URL, CONTROL_PLANE_URL);</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-dabefc" hidden>

<div class="rs-code">
  <div class="rs-code__head">kotlin<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-kotlin" data-lang="kotlin">// 1
val networkConfiguration = NetworkConfiguration(DATA_PLANE_URL)
// 2
val networkConfiguration = NetworkConfiguration(DATA_PLANE_URL, CONTROL_PLANE_URL)</code></pre></div>
</div>

</div>

</div>

<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="sessionconfiguration">SessionConfiguration</h3><p>The <a href="https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/mobile-trackers/tracking-events/#session" ><code>SessionConfiguration</code></a> class can be used to capture sessions to track the user activity in the app:</p>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-bcdefa"
		
		>Objective-C</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-cabefd"
		
		>Swift</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-fdbeca"
		
		>Java</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-dfbaec"
		
		>Kotlin</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-bcdefa">

<div class="rs-code">
  <div class="rs-code__head">objectivec<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-objectivec" data-lang="objectivec">RSSessionConfiguration *sessionConfig = [[RSSessionConfiguration alloc] initWithForegroundTimeout:[[NSMeasurement alloc] initWithDoubleValue:30 unit:NSUnitDuration.minutes] backgroundTimeout:[[NSMeasurement alloc] initWithDoubleValue:30 unit:NSUnitDuration.minutes]];

// 2
RSSessionConfiguration *sessionConfig = [[RSSessionConfiguration alloc] initWithForegroundTimeoutInSeconds:60 backgroundTimeoutInSeconds:60];</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-cabefd" hidden>

<div class="rs-code">
  <div class="rs-code__head">swift<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift">// 1
let sessionConfig = SessionConfiguration(
  foregroundTimeout: Measurement(value: 30, unit: .minutes),
  backgroundTimeout: Measurement(value: 30, unit: .minutes)
)

// 2
let sessionConfig = SessionConfiguration(foregroundTimeoutInSeconds: 60, backgroundTimeoutInSeconds: 60)</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-fdbeca" hidden>

<div class="rs-code">
  <div class="rs-code__head">java<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java">SessionConfiguration sessionConfiguration = new SessionConfiguration(
  new TimeMeasure(1, TimeUnit.MINUTES),
  new TimeMeasure(1, TimeUnit.MINUTES)
);</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-dfbaec" hidden>

<div class="rs-code">
  <div class="rs-code__head">kotlin<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-kotlin" data-lang="kotlin">val sessionConfiguration = SessionConfiguration(
  TimeMeasure(1, TimeUnit.MINUTES),
  TimeMeasure(1, TimeUnit.MINUTES)
);</code></pre></div>
</div>

</div>

</div>

<blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text">You need to pass both the arguments for the <code>SessionConfiguration</code> class as shown in the previous code snippets. However, RudderStack ignores the first argument (as it is a placeholder argument) and considers only the second argument (<code>backgroundTimeout</code>).</div>
  </div>
</blockquote>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">For mobile SDKs, Snowplow&rsquo;s default timeout session is 30 minutes whereas RudderStack&rsquo;s default timeout session is 5 minutes. Refer to the <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/session-tracking/#mobile-sdks" >RudderStack Session Tracking</a> documentation for more information.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="trackerconfiguration">TrackerConfiguration</h3><p>The <a href="https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/mobile-trackers/tracking-events/" ><code>TrackerConfiguration</code></a> class can be used to configure contexts and automatic events of the tracker and the general behavior, as shown in the following snippets:</p>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-aecfdb"
		
		>Objective-C</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-afecbd"
		
		>Swift</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-cabefd"
		
		>Java</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-befcda"
		
		>Kotlin</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-aecfdb">

<div class="rs-code">
  <div class="rs-code__head">objectivec<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-objectivec" data-lang="objectivec">RSTrackerConfiguration * trackerConfig = [
  [RSTrackerConfiguration alloc] init
];
[trackerConfig base64Encoding: YES];
[trackerConfig logLevel: LogLevelDebug];
[trackerConfig sessionContext: YES];
[trackerConfig deepLinkContext: YES];
[trackerConfig applicationContext: YES];
[trackerConfig platformContext: YES];
[trackerConfig geoLocationContext: NO];
[trackerConfig screenContext: YES];
[trackerConfig screenViewAutotracking: YES];
[trackerConfig lifecycleAutotracking: YES];
[trackerConfig installAutotracking: YES];
[trackerConfig exceptionAutotracking: YES];
[trackerConfig diagnosticAutotracking: NO];
[trackerConfig userAnonymisation: NO];
[trackerConfig appId: APP_ID];</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-afecbd" hidden>

<div class="rs-code">
  <div class="rs-code__head">swift<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift">let trackerConfig = TrackerConfiguration()
  .base64Encoding(false)
  .logLevel(.debug)
  .deepLinkContext(true)
  .applicationContext(true)
  .platformContext(true)
  .geoLocationContext(true)
  .lifecycleAutotracking(true)
  .diagnosticAutotracking(true)
  .screenViewAutotracking(true)
  .screenContext(true)
  .applicationContext(true)
  .exceptionAutotracking(true)
  .installAutotracking(true)
  .userAnonymisation(false)
  .appId(APP_ID)</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-cabefd" hidden>

<div class="rs-code">
  <div class="rs-code__head">java<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java">TrackerConfiguration trackerConfiguration = new TrackerConfiguration()
  .base64Encoding(false)
  .logLevel(LogLevel.VERBOSE)
  .deepLinkContext(true)
  .applicationContext(true)
  .platformContext(true)
  .geoLocationContext(true)
  .lifecycleAutotracking(true)
  .diagnosticAutotracking(true)
  .screenViewAutotracking(true)
  .screenContext(true)
  .applicationContext(true)
  .exceptionAutotracking(true)
  .installAutotracking(true)
  .userAnonymisation(false)
  .appId(APP_ID);</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-befcda" hidden>

<div class="rs-code">
  <div class="rs-code__head">kotlin<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-kotlin" data-lang="kotlin">val trackerConfiguration = TrackerConfiguration()
  .base64Encoding(false)
  .logLevel(LogLevel.VERBOSE)
  .deepLinkContext(true)
  .applicationContext(true)
  .platformContext(true)
  .geoLocationContext(true)
  .lifecycleAutotracking(true)
  .diagnosticAutotracking(true)
  .screenViewAutotracking(true)
  .screenContext(true)
  .applicationContext(true)
  .exceptionAutotracking(true)
  .installAutotracking(true)
  .userAnonymisation(false)
  .appId(APP_ID)</code></pre></div>
</div>

</div>

</div>

<p>Snowplow automatically captures and tracks the following data. Refer to the <a href="https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/mobile-trackers/tracking-events/#auto-tracked-events-and-entities" >Auto-tracked events and entities</a> section for more information.</p>
<table>
  <thead>
      <tr>
          <th>Variable name</th>
          <th>Default value</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>logLevel</code></td>
          <td><code>LogLevel.OFF</code></td>
      </tr>
      <tr>
          <td><code>lifecycleAutotracking</code></td>
          <td><code>true</code></td>
      </tr>
      <tr>
          <td><code>screenViewAutotracking</code></td>
          <td><code>true</code></td>
      </tr>
      <tr>
          <td><code>sessionContext</code></td>
          <td><code>true</code></td>
      </tr>
  </tbody>
</table>

<blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text">RudderStack ignores any variable other than the ones mentioned above.</div>
  </div>
</blockquote>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="subjectconfiguration">SubjectConfiguration</h3><p>The <a href="https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/mobile-trackers/tracking-events/" ><code>SubjectConfiguration</code></a> class can be used to capture basic user information which is attached to all events as the context entity.</p>

<blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text">Snowplow does not provide any call to identify a user. However, RudderStack sends an <a href="https://www.rudderstack.com/docs/event-spec/standard-events/identify/" ></a> call if you initialize the <code>SubjectConfiguration</code> class while initializing the SDK. <strong>Note that a user is not identified if the SDK is not initialized</strong>.</div>
  </div>
</blockquote>
<p>The <code>userId</code> field is mapped to the RudderStack&rsquo;s <code>userId</code>. All the other properties are mapped to RudderStack&rsquo;s <code>traits</code> object.</p>

<blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text"><code>userId</code> is a mandatory field. If not provided, the <code>identify</code> call is ignored.</div>
  </div>
</blockquote>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-eacdbf"
		
		>Objective-C</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-dabcef"
		
		>Swift</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-baefdc"
		
		>Java</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-dcfaeb"
		
		>Kotlin</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-eacdbf">

<div class="rs-code">
  <div class="rs-code__head">objectivec<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-objectivec" data-lang="objectivec">RSSubjectConfiguration * subjectConfig = [
  [RSSubjectConfiguration alloc] init
];
[subjectConfig userId: @ &#34;user_id&#34;];
[subjectConfig traits: @ {
  @ &#34;key_1&#34;: @ &#34;value_1&#34;, @ &#34;key_2&#34;: @20, @ &#34;key_3&#34;: @YES
}];</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-dabcef" hidden>

<div class="rs-code">
  <div class="rs-code__head">swift<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift">let subjectConfig = SubjectConfiguration()
  .userId(&#34;user_id&#34;)
  .traits([&#34;key_1&#34;: &#34;value_1&#34;, &#34;key_2&#34;: 20, &#34;key_3&#34;: true])</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-baefdc" hidden>

<div class="rs-code">
  <div class="rs-code__head">java<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java">Traits.Address address = new Traits.Address()
  .putCity(&#34;city value&#34;)
  .putCountry(&#34;country value&#34;)
  .putPostalCode(&#34;postalCode value&#34;)
  .putState(&#34;state value&#34;)
  .putStreet(&#34;street value&#34;);

Traits.Company company = new Traits.Company()
  .putName(&#34;name value&#34;)
  .putId(&#34;id value&#34;)
  .putIndustry(&#34;industry value&#34;);

Traits traits = new Traits()
  .putCompany(company)
  .putAddress(address)
  .putAge(&#34;age value&#34;)
  .putBirthday(&#34;birthday value&#34;)
  .putCreatedAt(&#34;createAt value&#34;)
  .putDescription(&#34;description value&#34;)
  .putEmail(&#34;email value&#34;)
  .putFirstName(&#34;fName value&#34;)
  .putGender(&#34;gender value&#34;)
  .putId(&#34;id value&#34;)
  .putLastName(&#34;lName value&#34;)
  .putName(&#34;name value&#34;)
  .putPhone(&#34;phone value&#34;)
  .putTitle(&#34;title value&#34;)
  .putUserName(&#34;userName value&#34;)
  .put(&#34;Key-1&#34;, &#34;value-1&#34;)
  .put(&#34;Key-2&#34;, 20)
  .put(&#34;Key-3&#34;, true);

SubjectConfiguration subjectConfiguration = new SubjectConfiguration()
  .userId(&#34;User-1&#34;)
  .traits(traits);</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-dcfaeb" hidden>

<div class="rs-code">
  <div class="rs-code__head">kotlin<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-kotlin" data-lang="kotlin">val address: Traits.Address = Traits.Address()
  .putCity(&#34;city value&#34;)
  .putCountry(&#34;country value&#34;)
  .putPostalCode(&#34;postalCode value&#34;)
  .putState(&#34;state value&#34;)
  .putStreet(&#34;street value&#34;)

val company: Traits.Company = Traits.Company()
  .putName(&#34;name value&#34;)
  .putId(&#34;id value&#34;)
  .putIndustry(&#34;industry value&#34;)

val traits = Traits()
  .putCompany(company)
  .putAddress(address)
  .putAge(&#34;age value&#34;)
  .putBirthday(&#34;birthday value&#34;)
  .putCreatedAt(&#34;createAt value&#34;)
  .putDescription(&#34;description value&#34;)
  .putEmail(&#34;email value&#34;)
  .putFirstName(&#34;fName value&#34;)
  .putGender(&#34;gender value&#34;)
  .putId(&#34;id value&#34;)
  .putLastName(&#34;lName value&#34;)
  .putName(&#34;name value&#34;)
  .putPhone(&#34;phone value&#34;)
  .putTitle(&#34;title value&#34;)
  .putUserName(&#34;userName value&#34;)
  .put(&#34;Key-1&#34;, &#34;value-1&#34;)
  .put(&#34;Key-2&#34;, 20)
  .put(&#34;Key-3&#34;, true)

val subjectConfiguration = SubjectConfiguration()
  .userId(&#34;User-1&#34;)
  .traits(traits)</code></pre></div>
</div>

</div>

</div>

<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="update-class-names">Update class names</h2><p>The following table lists the corresponding class names in Snowplow and RudderStack (mobile SDKs) which need to be updated based on your platform:</p>
<table>
  <thead>
      <tr>
          <th>Snowplow</th>
          <th></th>
          <th>RudderStack</th>
          <th></th>
          <th></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td></td>
          <td><strong>Java</strong></td>
          <td><strong>Kotlin</strong></td>
          <td><strong>Objective-C</strong></td>
          <td><strong>Swift</strong></td>
      </tr>
      <tr>
          <td><code>NetworkConfiguration</code></td>
          <td><code>NetworkConfiguration</code></td>
          <td><code>NetworkConfiguration</code></td>
          <td><code>RSNetworkConfiguration</code></td>
          <td><code>NetworkConfiguration</code></td>
      </tr>
      <tr>
          <td><code>TrackerConfiguration</code></td>
          <td><code>TrackerConfiguration</code></td>
          <td><code>TrackerConfiguration</code></td>
          <td><code>RSTrackerConfiguration</code></td>
          <td><code>TrackerConfiguration</code></td>
      </tr>
      <tr>
          <td><code>SessionConfiguration</code></td>
          <td><code>SessionConfiguration</code></td>
          <td><code>SessionConfiguration</code></td>
          <td><code>RSSessionConfiguration</code></td>
          <td><code>SessionConfiguration</code></td>
      </tr>
      <tr>
          <td><code>SubjectConfiguration</code></td>
          <td><code>SubjectConfiguration</code></td>
          <td><code>SubjectConfiguration</code></td>
          <td><code>RSSubjectConfiguration</code></td>
          <td><code>SubjectConfiguration</code></td>
      </tr>
      <tr>
          <td><code>Structured</code></td>
          <td><code>Structured</code></td>
          <td><code>Structured</code></td>
          <td><code>RSStructured</code></td>
          <td><code>Structured</code></td>
      </tr>
      <tr>
          <td><code>ScreenView</code></td>
          <td><code>ScreenView</code></td>
          <td><code>ScreenView</code></td>
          <td><code>RSScreenView</code></td>
          <td><code>ScreenView</code></td>
      </tr>
      <tr>
          <td><code>Background</code></td>
          <td><code>Background</code></td>
          <td><code>Background</code></td>
          <td><code>RSBackground</code></td>
          <td><code>Background</code></td>
      </tr>
      <tr>
          <td><code>Foreground</code></td>
          <td><code>Foreground</code></td>
          <td><code>Foreground</code></td>
          <td><code>RSForeground</code></td>
          <td><code>Foreground</code></td>
      </tr>
      <tr>
          <td><code>SelfDescribing</code></td>
          <td><code>SelfDescribing</code></td>
          <td><code>SelfDescribing</code></td>
          <td><code>RSSelfDescribing</code></td>
          <td><code>SelfDescribing</code></td>
      </tr>
      <tr>
          <td><code>SelfDescribingJson</code></td>
          <td><code>SelfDescribingJson</code></td>
          <td><code>SelfDescribingJson</code></td>
          <td><code>RSSelfDescribingJson</code></td>
          <td><code>SelfDescribingJson</code></td>
      </tr>
      <tr>
          <td><code>TimeMeasure</code></td>
          <td><code>TimeMeasure</code></td>
          <td><code>TimeMeasure</code></td>
          <td><code>N/A</code></td>
          <td><code>N/A</code></td>
      </tr>
      <tr>
          <td><code>Snowplow</code></td>
          <td><code>RSTracker</code></td>
          <td><code>RSTracker</code></td>
          <td><code>RSTracker</code></td>
          <td><code>RSTracker</code></td>
      </tr>
      <tr>
          <td><code>LogLevel</code></td>
          <td><code>LogLevel</code></td>
          <td><code>LogLevel</code></td>
          <td><code>LogLevel</code></td>
          <td><code>LogLevel</code></td>
      </tr>
  </tbody>
</table>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="send-events">Send events</h2><p>Migrate your existing events from Snowplow to RudderStack by following the below sections:</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="identify">Identify</h3><!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="ios-obj-candroid-java">iOS (Obj-C)/Android (Java)</h4><p>Snowplow&rsquo;s <a href="https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/mobile-trackers/tracking-events/" ><code>SubjectConfiguration</code></a> class can be used to identify users. See the <a href="#setting-configuration-objects" >Setting configuration objects</a> section for more information.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="javascript-1">JavaScript</h4><p>Snowplow supports identifying a user by passing the <code>setUserId</code> method. A Snowplow event including the <code>setUserId</code> method triggers the <a href="https://www.rudderstack.com/docs/event-spec/standard-events/identify/" ><code>identify</code></a> call in the RudderStack JavaScript SDK.</p>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">RudderStack supports only the <code>setUserId</code> method of the <a href="https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/javascript-trackers/javascript-tracker/javascript-tracker-v2/" >Snowplow v2 JS tracker</a>.</div>
  </div>
</blockquote>

</html>
<p>In the following sample call, <code>alex@example.com</code> is the <code>userId</code>, while <code>firstName</code>, <code>lastName</code>, and <code>city</code> are the user traits.</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rs.snowplowAdapter(&#39;setUserId&#39;, &#39;alex@example.com&#39;, {
  firstName: &#39;Alex&#39;,
  lastName: &#39;Keener&#39;,
  city: &#39;New Orleans&#39;
});</code></pre></div>
</div>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="track">Track</h3><!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="ios-obj-candroid-java-1">iOS (Obj-C)/Android (Java)</h4><!-- end-chunk -->
<!-- begin-chunk -->
<h5 id="custom-structured-events">Custom structured events</h5><p>RudderStack sends a <a href="https://www.rudderstack.com/docs/event-spec/standard-events/track/" ><code>track</code></a> call for Snowplow events containing the <a href="https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/mobile-trackers/tracking-events/#creating-a-structured-event" ><code>Structured</code></a> class.</p>
<p>In the following example, RudderStack maps <code>Action_example</code> to the RudderStack event name and the rest of the properties like <code>Category_example</code>, <code>label</code>, <code>value</code>, etc. to the RudderStack properties.</p>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-dcebfa"
		
		>Objective-C</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-afdbec"
		
		>Swift</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-afecdb"
		
		>Java</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-dfbeca"
		
		>Kotlin</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-dcebfa">

<div class="rs-code">
  <div class="rs-code__head">objectivec<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-objectivec" data-lang="objectivec">RSStructured * structured = [
  [RSStructured alloc] initWithCategory: @ &#34;Category_example&#34;
  action: @ &#34;Action_example&#34;
];
[structured label: @ &#34;my-label&#34;];
[structured property: @ &#34;my-property&#34;];
[structured value: @5];
[structured properties: @ {
  @ &#34;key_1&#34;: @ &#34;value_1&#34;, @ &#34;key_2&#34;: @ &#34;value_2&#34;
}];

[tracker track: structured];</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-afdbec" hidden>

<div class="rs-code">
  <div class="rs-code__head">swift<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift">let structured = Structured(category: &#34;Category_example&#34;, action: &#34;Action_example&#34;)
  .label(&#34;my-label&#34;)
  .property(&#34;my-property&#34;)
  .value(5)
  .properties([&#34;key_1&#34;: &#34;value_1&#34;, &#34;key_2&#34;: &#34;value_2&#34;])

tracker.track(structured)</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-afecdb" hidden>

<div class="rs-code">
  <div class="rs-code__head">java<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java">HashMap  properties = new HashMap  ();
properties.put(&#34;key-1&#34;, &#34;value 1&#34;);
properties.put(&#34;key-2&#34;, 123);
properties.put(&#34;key-3&#34;, 123.45);
properties.put(&#34;key-4&#34;, true);
properties.put(&#34;key-5&#34;, false);

Structured structured = new Structured(&#34;Category_example&#34;, &#34;Action_example&#34;)
  .label(&#34;my-label&#34;)
  .value(1234.23)
  .property(&#34;my-property&#34;)
  .properties(properties);

tracker.track(structured);</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-dfbeca" hidden>

<div class="rs-code">
  <div class="rs-code__head">kotlin<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-kotlin" data-lang="kotlin">val properties = mapOf&lt;string any=&#34;&#34;&gt;(
  &#34;key-1&#34; to &#34;value 1&#34;,
  &#34;key-2&#34; to 123,
  &#34;key-3&#34; to 123.45,
  &#34;key-4&#34; to true,
  &#34;key-5&#34; to false
)

val structured = Structured(&#34;Category_example&#34;, &#34;Action_example&#34;)
  .label(&#34;my-label&#34;)
  .value(1234.23)
  .property(&#34;my-property&#34;)
  .properties(properties)

tracker.track(structured)</code></pre></div>
</div>

</div>

</div>

<!-- end-chunk -->
<!-- begin-chunk -->
<h5 id="custom-self-described-events">Custom self-described events</h5><p>RudderStack sends a <a href="https://www.rudderstack.com/docs/event-spec/standard-events/track/" >track</a> call for Snowplow events containing the <a href="https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/mobile-trackers/tracking-events/#creating-a-structured-event" ><code>SelfDescribing</code></a> class.</p>
<p>In the following example, RudderStack maps <code>action</code> to the RudderStack event name.</p>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-ecafbd"
		
		>Objective-C</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-ebcadf"
		
		>Swift</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-fecdba"
		
		>Java</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-feacbd"
		
		>Kotlin</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-ecafbd">

<div class="rs-code">
  <div class="rs-code__head">objectivec<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-objectivec" data-lang="objectivec">// 1
RSSelfDescribingJson * selfDescribingJson = [
  [RSSelfDescribingJson alloc] initWithSchema: @ &#34;schema&#34;
  andDictionary: @ {
    @ &#34;action&#34;: @ &#34;Action_2&#34;, @ &#34;key_2&#34;: @ &#34;value_2&#34;
  }
];
RSSelfDescribing * selfDescribing = [
  [RSSelfDescribing alloc] initWithEventData: selfDescribingJson
];

// 2
RSSelfDescribing * selfDescribing = [
  [RSSelfDescribing alloc] initWithSchema: @ &#34;schema&#34;
  payload: @ {
    @ &#34;action&#34;: @ &#34;Action_2&#34;, @ &#34;key_2&#34;: @ &#34;value_2&#34;
  }
];

[tracker track: selfDescribing];</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-ebcadf" hidden>

<div class="rs-code">
  <div class="rs-code__head">swift<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift">// 1
let selfDescribingJson = SelfDescribingJson(schema: &#34;schema&#34;, andDictionary: [&#34;action&#34;: &#34;Action_2&#34;])
let selfDescribing = SelfDescribing(eventData: selfDescribingJson)

// 2
let selfDescribing = SelfDescribing(schema: &#34;schema&#34;, payload: [&#34;action&#34;: &#34;Action_2&#34;])

tracker.track(selfDescribing)</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-fecdba" hidden>

<div class="rs-code">
  <div class="rs-code__head">java<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java">HashMap  properties = new HashMap  ();
properties.put(&#34;action&#34;, &#34;Action-2&#34;);
properties.put(&#34;key-1&#34;, &#34;value 1&#34;);

// 1
SelfDescribingJson selfDescribingJson = new SelfDescribingJson(&#34;schema&#34;, payload)
SelfDescribing selfDescribing = new SelfDescribing(selfDescribingJson)

// 2
SelfDescribing selfDescribing = new SelfDescribing(&#34;schema&#34;, payload)

tracker.track(selfDescribing);</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-feacbd" hidden>

<div class="rs-code">
  <div class="rs-code__head">kotlin<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-kotlin" data-lang="kotlin">val payload = mapOf  (
	  &#34;action&#34; to &#34;Action-2&#34;,
	  &#34;key-2&#34; to &#34;value-2&#34;
	)

// 1
val selfDescribingJson = SelfDescribingJson(&#34;schema&#34;, payload)
val selfDescribing = SelfDescribing(selfDescribingJson)

// 2
val selfDescribing = SelfDescribing(&#34;schema&#34;, payload)

tracker.track(selfDescribing)</code></pre></div>
</div>

</div>

</div>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text"><code>action</code> is a mandatory field. RudderStack does not send any call if it is absent.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h5 id="custom-foreground-events">Custom foreground events</h5><p>RudderStack sends a <a href="https://www.rudderstack.com/docs/event-spec/standard-events/track/" >track</a> call for Snowplow events containing the <a href="https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/mobile-trackers/previous-versions/objective-c-tracker/objective-c-1-0-0/#foreground-and-background-events" ><code>Foreground</code></a> class.</p>
<p>RudderStack sends the event name as <code>Application Opened</code> and maps the rest of the properties like <code>index</code>, <code>properties</code>, etc. to the RudderStack properties.</p>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-cdaebf"
		
		>Objective-C</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-dbeafc"
		
		>Swift</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-bcefad"
		
		>Java</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-cadbef"
		
		>Kotlin</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-cdaebf">

<div class="rs-code">
  <div class="rs-code__head">objectivec<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-objectivec" data-lang="objectivec">RSForeground * foreground = [
  [RSForeground alloc] initWithIndex: @1
];
[foreground properties: @ {
  @ &#34;key_1&#34;: @ &#34;value_1&#34;
}];

[tracker track: foreground];</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-dbeafc" hidden>

<div class="rs-code">
  <div class="rs-code__head">swift<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift">let foreground = Foreground(index: 1)
  .properties([&#34;key_1&#34;: &#34;value_1&#34;])

tracker.track(foreground)</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-bcefad" hidden>

<div class="rs-code">
  <div class="rs-code__head">java<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java">HashMap  properties = new HashMap  ();
properties.put(&#34;key-1&#34;, &#34;value 1&#34;);
properties.put(&#34;key-2&#34;, 123);
properties.put(&#34;key-3&#34;, 123.45);
properties.put(&#34;key-4&#34;, true);
properties.put(&#34;key-5&#34;, false);

Foreground foreground = new Foreground(1234);
foreground.setProperties(properties);

tracker.track(foreground);</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-cadbef" hidden>

<div class="rs-code">
  <div class="rs-code__head">kotlin<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-kotlin" data-lang="kotlin">val properties = mapOf&lt;string any=&#34;&#34;&gt;(
  &#34;key-1&#34; to &#34;value 1&#34;,
  &#34;key-2&#34; to 123,
  &#34;key-3&#34; to 123.45,
  &#34;key-4&#34; to true,
  &#34;key-5&#34; to false
)

Foreground foreground = Foreground(1234)
foreground.properties = properties

tracker.track(background)</code></pre></div>
</div>

</div>

</div>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">This is not a default <a href="https://www.rudderstack.com/docs/event-spec/standard-events/application-lifecycle-events-spec/" >application lifecycle event</a>. Hence, the properties like <code>version</code>, <code>build</code>, etc. are not present under <code>properties</code>.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h5 id="custom-background-events">Custom background events</h5><p>RudderStack sends a <a href="https://www.rudderstack.com/docs/event-spec/standard-events/track/" >track</a> call for Snowplow events containing the <a href="https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/mobile-trackers/previous-versions/objective-c-tracker/objective-c-1-0-0/#foreground-and-background-events" ><code>Background</code></a> class.</p>
<p>RudderStack sends the event name as <code>Application Backgrounded</code> and maps the rest of the properties, like <code>index</code>, <code>properties</code>, etc. to the RudderStack properties.</p>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-fdaebc"
		
		>Objective-C</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-bcdefa"
		
		>Swift</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-cdefab"
		
		>Java</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-cadfbe"
		
		>Kotlin</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-fdaebc">

<div class="rs-code">
  <div class="rs-code__head">objectivec<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-objectivec" data-lang="objectivec">RSBackground * background = [
  [RSBackground alloc] initWithIndex: @1
];
[background properties: @ {
  @ &#34;key_1&#34;: @ &#34;value_1&#34;
}];

[tracker track: background];</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-bcdefa" hidden>

<div class="rs-code">
  <div class="rs-code__head">swift<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift">let background = Background(index: 1)
  .properties([&#34;key_1&#34;: &#34;value_1&#34;])

tracker.track(background)</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-cdefab" hidden>

<div class="rs-code">
  <div class="rs-code__head">java<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java">HashMap  properties = new HashMap  ();
properties.put(&#34;key-1&#34;, &#34;value 1&#34;);
properties.put(&#34;key-2&#34;, 123);
properties.put(&#34;key-3&#34;, 123.45);
properties.put(&#34;key-4&#34;, true);
properties.put(&#34;key-5&#34;, false);

Background background = new Background(1234);
background.setProperties(properties);

tracker.track(background);</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-cadfbe" hidden>

<div class="rs-code">
  <div class="rs-code__head">kotlin<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-kotlin" data-lang="kotlin">val properties = mapOf&lt;string any=&#34;&#34;&gt;(
  &#34;key-1&#34; to &#34;value 1&#34;,
  &#34;key-2&#34; to 123,
  &#34;key-3&#34; to 123.45,
  &#34;key-4&#34; to true,
  &#34;key-5&#34; to false
)

Background background = Background(1234)
background.properties = properties

tracker.track(background)</code></pre></div>
</div>

</div>

</div>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">This is not a default <a href="https://www.rudderstack.com/docs/event-spec/standard-events/application-lifecycle-events-spec/" >application lifecycle event</a>. Hence, the properties like <code>version</code>, <code>build</code>, etc. are not present under <code>properties</code>.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="javascript-2">JavaScript</h4><p>The RudderStack JavaScript SDK supports Snowplow&rsquo;s <code>trackStructEvent</code> and <code>trackSelfDescribingEvent</code> calls. These Snowplow calls capture user events along with their associated properties and trigger the <a href="https://www.rudderstack.com/docs/event-spec/standard-events/track/" ><code>track</code></a> call in the RudderStack JavaScript SDK.</p>
<p>A sample <code>trackSelfDescribingEvent</code> call:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rs.snowplowAdapter(&#39;trackSelfDescribingEvent&#39;, {
  event: {
    data: {
      action: &#39;order completed&#39;,
      category: &#39;FCW&#39;,
      product_id: &#39;P1100DFG9766&#39;,
      revenue: 30,
      currency: &#39;USD&#39;,
      user_actual_id: 12345,
    },
  },
}); 
</code></pre></div>
</div>
<p>In the previous code snippet, the <code>trackSelfDescribingEvent</code> method tracks the <code>Order Completed</code> event along with other information like <code>revenue</code>, <code>currency</code>, and <code>user_actual_id</code>, etc.</p>
<p>A sample <code>trackStructEvent</code> call:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rs.snowplowAdapter(&#39;trackStructEvent&#39;, {
  action: &#39;order completed&#39;,
  category: &#39;FCW&#39;,
  label: &#39;Sample label&#39;,
  property: &#39;Some property&#39;,
  value: 40.0,
});</code></pre></div>
</div>
<p>In the previous code snippet, the <code>trackStructEvent</code> method tracks the <code>Order Completed</code> event along with other information like <code>label</code>, <code>property</code>, and <code>value</code>, etc.</p>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">The <code>action</code> field is mandatory in both calls.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="track-page-or-screen-views">Track page or screen views</h3><!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="ios-obj-candroid-java-2">iOS (Obj-C)/Android (Java)</h4><p>Snowplow&rsquo;s <a href="https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/mobile-trackers/tracking-events/#creating-a-structured-event" ><code>ScreenView</code></a> class captures whenever a new screen is loaded. A Snowplow event including the <code>ScreenView</code> class triggers the <a href="https://www.rudderstack.com/docs/event-spec/standard-events/screen/" ><code>screen</code></a> call in the RudderStack iOS (Obj-C) or Android (Java) SDK.</p>
<p>RudderStack maps the <code>name</code> property to RudderStack event name and the rest of the properties, like <code>screenId</code>, <code>previousName</code>, <code>previousId</code>, etc. to the RudderStack properties.</p>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-eabfcd"
		
		>Objective-C</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-bcaefd"
		
		>Swift</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-acbedf"
		
		>Java</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-efbadc"
		
		>Kotlin</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-eabfcd">

<div class="rs-code">
  <div class="rs-code__head">objectivec<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-objectivec" data-lang="objectivec">RSScreenView * screen = [
  [RSScreenView alloc] initWithName: @ &#34;DemoScreenName&#34;
  screenId: [
    [NSUUID alloc] init
  ]
];
[screen type: @ &#34;type&#34;];
[screen previousName: @ &#34;previousName&#34;];
[screen previousId: @ &#34;previousId&#34;];
[screen previousType: @ &#34;previousType&#34;];
[screen transitionType: @ &#34;transitionType&#34;];
[screen viewControllerClassName: @ &#34;viewControllerClassName&#34;];
[screen topViewControllerClassName: @ &#34;topViewControllerClassName&#34;];
[screen properties: @ {
  @ &#34;key_1&#34;: @ &#34;value_1&#34;,
    @ &#34;key_2&#34;: @ &#34;value_2&#34;
}];

[tracker track: screen];</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-bcaefd" hidden>

<div class="rs-code">
  <div class="rs-code__head">swift<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift">let screen = ScreenView(name: &#34;DemoScreenName&#34;, screenId: UUID())
  .type(&#34;type&#34;)
  .previousName(&#34;previousName&#34;)
  .previousId(&#34;previousId&#34;)
  .previousType(&#34;previousType&#34;)
  .transitionType(&#34;transitionType&#34;)
  .viewControllerClassName(&#34;viewControllerClassName&#34;)
  .topViewControllerClassName(&#34;topViewControllerClassName&#34;)
  .properties: ([
    &#34;key_1&#34;: &#34;value_1&#34;,
    &#34;key_2&#34;: &#34;value_2&#34;
  ])

tracker.track(screen)</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-acbedf" hidden>

<div class="rs-code">
  <div class="rs-code__head">java<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java">ScreenView screenView = new ScreenView(&#34;MainActivity&#34;, UUID.randomUUID())
  .type(&#34;type&#34;)
  .previousName(&#34;previousName&#34;)
  .previousId(&#34;previousId&#34;)
  .previousType(&#34;previousType&#34;)
  .transitionType(&#34;transitionType&#34;);

tracker.track(screenView);</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-efbadc" hidden>

<div class="rs-code">
  <div class="rs-code__head">kotlin<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-kotlin" data-lang="kotlin">val screenView = ScreenView(&#34;MainActivity&#34;, UUID.randomUUID())
  .type(&#34;type&#34;)
  .previousName(&#34;previousName&#34;)
  .previousId(&#34;previousId&#34;)
  .previousType(&#34;previousType&#34;)
  .transitionType(&#34;transitionType&#34;)

tracker.track(screenView)</code></pre></div>
</div>

</div>

</div>

<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="javascript-3">JavaScript</h4><p>Snowplow&rsquo;s <code>trackPageView</code> call lets you record your website&rsquo;s page views with any additional relevant information about the viewed page. A Snowplow event including the <code>trackPageView</code> call triggers the <a href="https://www.rudderstack.com/docs/event-spec/standard-events/screen/" >screen</a> call in the RudderStack JavaScript SDK.</p>
<p>A sample <code>trackPageView</code> call:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rs.snowplowAdapter(
  &#39;trackPageView&#39;,
  {
    title: &#39;Cart Viewed&#39;,
  },
  {
    path: &#39;/best-seller/1&#39;,
    referrer: &#39;https://www.google.com/search?q=estore+bestseller&#39;,
    search: &#39;estore bestseller&#39;,
    title: &#39;The best sellers offered by EStore&#39;,
    url: &#39;https://www.estore.com/best-seller/1&#39;,
  },
);</code></pre></div>
</div>
<p>In the previous code snippet, the SDK captures the page title and other <a href="https://www.rudderstack.com/docs/event-spec/standard-events/common-fields/#contextual-fields" >contextual information</a>.</p>
<br />

