Skip to content

Context Insights

This page explains how to use ContextSDK to get insights into how your app is being used in the real world for Context Insights.

Overview

  • Step 1: Add ContextSDK to your app
  • Step 2: Log events
  • Step 3: Ship an App Store update with ContextSDK

Impact on your app

Less than 0.2% CPU Usage

0.6 MB Memory Usage

Adds less than 700kb to your app's binary size

No PII processed or stored

No app permissions required

Operates without ATT

Installation

Add https://github.com/context-sdk/context-sdk-releases as dependency.

Add the following dependency to your Podfile and run pod install

pod 'ContextSDK'

  1. Download the latest release: https://storage.googleapis.com/de73e410-context-sdk-releases/latest/ContextSDK.zip
  2. Drag & Drop the ContextSDK.xcframework folder into the Xcode file list
  3. Go to your project settings, scroll down to Frameworks, Libraries, and Embedded Content, add ContextSDK.xcframework, and select Embed & Sign

If you want to download a specific version, you can replace latest with the desired version number, e.g. https://storage.googleapis.com/de73e410-context-sdk-releases/3.1.0/ContextSDK.zip

Step 1: Add the ContextSDK maven repository in your project level settings.gradle.kts file:

dependencyResolutionManagement {
    repositories {
        ...

        // Add the ContextSDK maven repo:
        maven {
            url = uri("https://storage.googleapis.com/fc4073e9-contextsdk-maven/")
        }
    }
}

Step 2: Add the ContextSDK dependency in your module level build.gradle.kts:

dependencies {
  ...

  implementation("com.contextsdk:contextsdk:1.0.0")
}

Step 1: Choose your preferred package manager:

npm install react-native-context-sdk@latest
yarn add react-native-context-sdk

Step 2: Ensure minimum Deployment Target

ContextSDK requires a minimum deployment target of iOS 14.0, be sure to update your ios/Podfile to specify 14.0 or higher:

platform :ios, '14.0'
  1. Download the latest version of ContextSDK: https://storage.googleapis.com/de73e410-context-sdk-releases/latest/ContextSDK.zip
  2. Drag & drop the ContextSDK.xcframework into the Assets/Plugins/iOS folder of your Unity project
  3. Add the ContextSDKBinding.cs script next to it
  1. Add context_sdk to your pubspec.yaml

  2. Ensure minimum Deployment Target is iOS 14.0 or higher. Be sure to update your ios/Podfile to specify 14.0 or higher:

platform :ios, '14.0'

License Key

After you installed ContextSDK, you need to add your license key. Register here to get started.

In your willFinishLaunchingWithOptions: (or anywhere before you access the SDK) setup the ContextManager:

AppDelegate.swift
import ContextSDK
AppDelegate.swift willFinishLaunchingWithOptions:
ContextManager.setup("YOUR_LICENSE_KEY")
  1. Create a new custom Swift class named AppDelegate.swift
    AppDelegate.swift
    import ContextSDK
    
    class AppDelegate: NSObject, UIApplicationDelegate {
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
            ContextManager.setup("YOUR_LICENSE_KEY")
            return true
        }
    }
    
  2. In your App scene UIApplicationDelegateAdaptor property wrapper
    struct YourApp: App {
        @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
        // ...
    }
    

Note: Android is still in beta - to obtain a license key contact us at support@contextsdk.com

  1. In your Application sub-class call the following code:
class MainApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        ContextSDK.setup(this, "YOUR_LICENSE_KEY_HERE")
    }
}
  1. In your primary Activity subclass, or in every Activity in your application, allow ContextSDK to attach and detach:
class MainActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ContextSDK.attachToActivity(this)
  }

  override fun onDestroy() {
    super.onDestroy()
    ContextSDK.detachFromActivity(this)
  }
}
  1. In your Application sub-class call the following code:
public class MainApplication extends Application {

  @Override
  public void onCreate() {
    super.onCreate();
    ContextSDK.Companion.setup(this, "YOUR_LICENSE_KEY_HERE", new ContextSDKConfiguration());
  }
}
  1. In your primary Activity subclass, or in every Activity in your application, allow ContextSDK to attach and detach:
public class MainActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ContextSDK.Companion.attachToActivity(this);
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    ContextSDK.Companion.detachFromActivity(this);
  }
}

Notes:

  • If the above isn't setup correctly, ContextSDK won't be able to start and stop collection of accelerometer & gyroscope data.
  • The Activity must conform to LifecycleOwner (e.g. AppCompatActivity). Plain Activities are not supported.

Call the following code on app start:

import { setup } from 'react-native-context-sdk';

void setup("YOUR_LICENSE_KEY_HERE");

In the Start() of a MonoBehaviour that is run early in your game (or anywhere before you access the SDK) setup the ContextManager:

InitContextSDK.cs
using static ContextSDKBinding;

public class InitContextSDK : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        ContextSDKBinding.SetupWithAPIBackend("YOUR_LICENSE_KEY");
    }
}

Call the following code on app start:

import 'package:context_sdk/context_sdk.dart';

final _contextSdkPlugin = ContextSdk();

_contextSdkPlugin.setup("YOUR_LICENSE_KEY_HERE");

Log Events

We recommend you log specific events to get a better understanding of how the real world context influences your app.

Page Views

Use this to track users navigating through different screen in your app. It allow us to provide you insights into which screen is most commonly used in which real world context.

ContextManager.trackPageView("page_identifier")
ContextSDK.trackPageView("page_identifier");
import { trackPageView } from 'react-native-context-sdk';

trackPageView("page_identifier");
ContextSDKBinding.TrackPageView("page_identifier");
_contextSdkPlugin.trackPageView("page_identifier");

User Actions

Use this to track certain user actions, like when a user enabled a certain feature, when a user tapped a button, when the user created an account, or when the user shared something. This allows us to provide you insights into which user actions are most commonly done in which real world context.

ContextManager.trackUserAction("user_tapped_share_button")
ContextSDK.trackUserAction("user_tapped_share_button");
import { trackUserAction } from 'react-native-context-sdk';

trackUserAction("user_tapped_share_button");
ContextSDKBinding.TrackUserAction("user_tapped_share_button");
_contextSdkPlugin.trackUserAction("user_tapped_share_button");

Generic Events

Use this to track certain events in your app. This can be used generically to track any type of event. For example, you can add this to your existing analytics code to log all your existing events into ContextSDK. This allows us to provide you insights into which events are most commonly triggered in which real world context.

ContextManager.trackEvent("custom_event")
ContextSDK.trackEvent("custom_event");
import { trackEvent } from 'react-native-context-sdk';

trackEvent("custom_event");
ContextSDKBinding.TrackEvent("custom_event");
_contextSdkPlugin.trackEvent("custom_event");

Conversion & Upsells

Logging the outcome of sales events (e.g. in-app purchases, orders, etc.) allows us to provide you with detailed insights in which real world context has a positive or negative effect on your app's conversion rates.

The integration is slightly more complex, as you need to track the context before before you show the prompt, and then log the outcome after the user has made a decision.


  • Use a different, unique flowName for each upsell funnel (e.g. upsell_prompt, upsell_onboarding, etc.)
    • If you have the same purchase flow, but from different parts of your app, use a different flowName for each.
    • We automatically analyze the overlap between different flows, to decide if there should be one, or more models.
  • The timing is crucial: You need to create the context object right before showing your prompt, and then log the outcome of the user interaction after the user has either accepted or dismissed the prompt.
  • For each context object you create, be sure to log an outcome, even if the user dismisses the prompt.

In most cases, ContextSDK will execute your block instantly. Only if your app was recently launched, or resumed from the background, it will take up to a few seconds to get a full context.

ContextManager.optimize("upsell") { context in
    // [Show the upgrade prompt here right after fetching the context]
    // Once you know if the user purchased or dismissed the upsell, log the outcome:
    context.log(.positive) // or .negative
}
ContextSDK.optimize("upsell") { context ->
    // [Show the upgrade prompt here right after fetching the context]
    // Once you know if the user purchased or dismissed the upsell, log the outcome:
    context.log(EventOutcome.POSITIVE) // or EventOutcome.NEGATIVE
}
import { optimize } from 'react-native-context-sdk';
import { Outcome } from 'react-native-context-sdk/lib/typescript/src/context';

optimize({
    flowName: 'upsell',
    onGoodMoment: async (context) => {
        // Show the upgrade prompt here right after fetching the context
        // Once you know if the user purchased or dismissed the upsell, log the outcome:
        context.log(Outcome.positive); // or Outcome.negative
    },
});
ContextSDKBinding.Optimize("upsell", delegate (Context context) {
    // Show the upgrade prompt here right after fetching the context
    // Once you know if the user purchased or dismissed the upsell, log the outcome:
    context.Log(Outcome.Positive); // or Outcome.Negative
});
_contextSdkPlugin.optimize("upsell", (context) async {
    // Show the upgrade prompt here right after fetching the context
    // Once you know if the user purchased or dismissed the upsell, log the outcome:
    await context.log(Outcome.positive);
});

It's critical you trigger your prompt inside the block, which behaves as follows:

  • The callback is instantly executed if your app has been running for at least 3 seconds
  • The callback being executed within 3 seconds if your app was just put into the foreground recently

If you decide to use Context Decision in the future to start optimizing your app, your block will only be executed when we deem it to be a good moment.


Forcing instant callbacks when tracking conversions

There are cases where you may prefer to always instantly have your callback executed. For example, when you want to show a prompt right after a certain user-action, to prevent the prompt showing up when the user already left the screen. For those cases, you'd need to use the ContextManager.optimize method with the maxDelay: 0 parameter:

ContextManager.optimize("upsell", maxDelay: 0) { context in
    // [Show the upgrade prompt here right after fetching the context]
    // Once you know if the user purchased or dismissed the upsell, log the outcome:
    context.log(.positive) // or .negative
}
ContextSDK.optimize("upsell", maxDelayS = 0) { context ->
    // [Show the upgrade prompt here right after fetching the context]
    // Once you know if the user purchased or dismissed the upsell, log the outcome:
    context.log(EventOutcome.POSITIVE) // or EventOutcome.NEGATIVE
}
import { optimize } from 'react-native-context-sdk';
import { Outcome } from 'react-native-context-sdk/lib/typescript/src/context';

optimize({
    flowName: 'upsell',
    maxDelay: 0,
    onGoodMoment: async (context) => {
        // Show the upgrade prompt here right after fetching the context
        // Once you know if the user purchased or dismissed the upsell, log the outcome:
        context.log(Outcome.positive); // or Outcome.negative
    },
});
ContextSDKBinding.Optimize("upsell", delegate (Context context) {
    // Setting maxDelay to 0 (below as extra parameter) causes the callback to be called immediately.

    // Show the upgrade prompt here right after fetching the context
    // Once you know if the user purchased or dismissed the upsell, log the outcome:
    context.Log(Outcome.Positive); // or Outcome.Negative
}, null, 0);
 _contextSdkPlugin.optimize("upsell", maxDelay: 0, (context) async {
  // Show the upgrade prompt here right after fetching the context
  // Once you know if the user purchased or dismissed the upsell, log the outcome:
  await context.log(Outcome.positive);
})

Using maxDelay: 0 means that the context object may not be fully ready, which will reduce data quality. We recommend not using this approach right after the app start, but only in places where the app usually has already been running for a few seconds.


We also support some additional helpers, which you can find in our Context Decision Docs.

Go Live

Now all that's left is to ship your update to the App Store to start gaining context insights. Continue to the release page for a final check before shipping, as well as other deployment tips.