Skip to content

Release

Before you ship your first release with the ContextSDK, we recommend taking a few steps to validate the integration works as expected.

Step 1: Validate the Context

  1. Add the following line right after wherever you get access to the context object:
    ContextManager.optimize(flowName: "upsell") { context in
      print(context.validate())
      // [Your remaining code here]
    }
    
  2. Run your app on a physical iPhone device, not on a simulator
  3. Navigate to the screen where you access ContextSDK. Make sure all the requirements you've implemented in your app are met (e.g. the user has not purchased the product, the user has not seen the upsell before, etc.).
  4. You should see the following output printed, with the numbers varying depending on the current context:
    ✅ Number of Signals: 195 (this number may be higher)
    ✅ Flow name provided: your_flow_name  
    ✅ Accelerometer Data: Valid
    👉 Signal Sample 1: 0.0 (if your device was flat on the table not moving, this should be 0.0)
    👉 Signal Sample 2: 0.0059286836 (this should never be exactly 0.0)
    ✅ Calibration Mode active
    ✅ ContextSDK License: Active
    👉 ContextSDK Version: 4.8.0
    
  5. If you notice the ContextSDK version not being 4.8.0, please follow the update instructions.
  1. Add the following line right after wherever you get access to the context object:
    ContextSDK.optimize("upsell") { context ->
      Log.d("ContextSDK", context.validate())
      // [Your remaining code here]
    }
    
  2. Run your app on a physical iPhone device, not on a simulator
  3. Navigate to the screen where you access ContextSDK. Make sure all the requirements you've implemented in your app are met (e.g. the user has not purchased the product, the user has not seen the upsell before, etc.).
  4. You should see the following output printed, with the numbers varying depending on the current context:
    ✅ Number of Signals: 195 (this number may be higher)
    ✅ Flow name provided: your_flow_name  
    ✅ Accelerometer Data: Valid
    👉 Signal Sample 1: 0.0 (if your device was flat on the table not moving, this should be 0.0)
    👉 Signal Sample 2: 0.0059286836 (this should never be exactly 0.0)
    ✅ Calibration Mode active
    ✅ ContextSDK License: Active
    👉 ContextSDK Version: 4.8.0
    
  5. If you notice the ContextSDK version not being 4.8.0, please follow the update instructions.
  1. Add the following line right after wherever you get access to the context object:
    optimize({
        flowName: 'upsell',
        onGoodMoment: async (context) => {
          const output = await context.validate();
          console.log(output); // Or print it anywhere else
          // [Your remaining code here]
        },
      });
    
  2. Run your app on a physical iPhone device, not on a simulator
  3. Navigate to the screen where you access ContextSDK. Make sure all the requirements you've implemented in your app are met (e.g. the user has not purchased the product, the user has not seen the upsell before, etc.).
  4. You should see the following output printed, with the numbers varying depending on the current context:
    ✅ Number of Signals: 195 (this number may be higher)
    ✅ Flow name provided: your_flow_name  
    ✅ Accelerometer Data: Valid
    👉 Signal Sample 1: 0.0 (if your device was flat on the table not moving, this should be 0.0)
    👉 Signal Sample 2: 0.0059286836 (this should never be exactly 0.0)
    ✅ Calibration Mode active
    ✅ ContextSDK License: Active
    👉 ContextSDK Version: 4.8.0
    
  5. If you notice the ContextSDK version not being 4.8.0, please follow the update instructions.
  1. Add the following line right after wherever you get access to the context object:
    ContextSDKBinding.Optimize("upsell", delegate (Context context) {
      Debug.Log(context.Validate());
      // [Your remaining code here]
    })
    
  2. Run your app on a physical iPhone device, not on a simulator
  3. Navigate to the screen where you access ContextSDK. Make sure all the requirements you've implemented in your app are met (e.g. the user has not purchased the product, the user has not seen the upsell before, etc.).
  4. You should see the following output printed, with the numbers varying depending on the current context:
    ✅ Number of Signals: 195 (this number may be higher)
    ✅ Flow name provided: your_flow_name  
    ✅ Accelerometer Data: Valid
    👉 Signal Sample 1: 0.0 (if your device was flat on the table not moving, this should be 0.0)
    👉 Signal Sample 2: 0.0059286836 (this should never be exactly 0.0)
    ✅ Calibration Mode active
    ✅ ContextSDK License: Active
    👉 ContextSDK Version: 4.8.0
    
  5. If you notice the ContextSDK version not being 4.8.0, please follow the update instructions.
  1. Add the following line right after wherever you get access to the context object:
    _contextSdkPlugin.optimize("upsell", (context) async {
      print(await context.validate());
      // [Your remaining code here]
    });
    
  2. Run your app on a physical iPhone device, not on a simulator
  3. Navigate to the screen where you access ContextSDK. Make sure all the requirements you've implemented in your app are met (e.g. the user has not purchased the product, the user has not seen the upsell before, etc.).
  4. You should see the following output printed, with the numbers varying depending on the current context:
    ✅ Number of Signals: 195 (this number may be higher)
    ✅ Flow name provided: your_flow_name  
    ✅ Accelerometer Data: Valid
    👉 Signal Sample 1: 0.0 (if your device was flat on the table not moving, this should be 0.0)
    👉 Signal Sample 2: 0.0059286836 (this should never be exactly 0.0)
    ✅ Calibration Mode active
    ✅ ContextSDK License: Active
    👉 ContextSDK Version: 4.8.0
    
  5. If you notice the ContextSDK version not being 4.8.0, please follow the update instructions.

Step 2: Validate Reporting

Login to the Context Dashboard and verify that the data is being collected correctly.

Step 3: Verify each upsell flow uses a unique flowName

If your app has multiple screens or flows in which the user may upgrade or purchase their account, be sure to use different, unique flowName values (e.g. upsell_prompt, upsell_onboarding, upsell_from_settings_screen, etc.)

We automatically analyze the overlap between different flows, to decide if there should be one, or more models.

Step 4: Verify the moment you access context

It is critical that you create your context object right before you show the upsell prompt within its block. This guarantees that the signals are taken at the correct moment (as context can change quickly), and also allows you to start making decisions once your custom model is ready.

Step 5: Verify you are correctly logging all outcome scenarios

You need to ensure you always log at least one outcome for each time you access the current context:

We recommend logging .positive only after the user successfully completes a purchase.

If the user dismisses the iOS payment sheet or encounters a transaction error (e.g., due to network issues), avoid logging an outcome immediately. Instead, log a new outcome metadata and allow the user to retry (e.g., by keeping the paywall screen open after a payment error). Log the final outcome later, such as when the user either dismisses the paywall (log .negative) or successfully completes the purchase (log .positive).

Alternatively, you can be more fine-grained with your logging and use

  • .positiveInteracted: The user has started the purchase flow, or read more about the offer, but cancelled the payment flow
  • .positiveConverted: The user ended up successfully purchasing the product (all the way through the payment flow)

If you are logging additional outcome metadata, make sure to call context.log(…) at some point afterwards, because the metadata is only sent to the server when logging an outcome.

Lastly, keep in mind that there is no value in logging multiple outcomes for the same context object if you are not adding additional outcome metadata in-between each method. If the user dismisses the upsell prompt, there is no need to log a .negative outcome multiple times if you are not updating any metadata in-between these events. So in your application, either make sure to update the metadata between each outcome, or only log the outcome once.

Step 6: Ensure no ContextSDK errors are logged

When running your app with ContextSDK installed on a real device, ensure that Xcode doesn't print out any ContextSDK related errors (search console logs for "ContextSDK")