Welcome to our new beta documentation experience! Let us know what you think below, under "Was this article helpful?" 👍 👎

Initialize the App SDK

Prev Next

Flowchart illustrating steps for Usercentrics SDK integration and consent management process.

Let's review some basics on when to initialize Usercentrics and legal requirements.

When to present the banner?

In general, you are free to decide when to present the banner to your users. e.g. Right after app launch, after login, during app onboarding, etc.

There is only 1 requirement when deciding when to do this:

Do NOT enable any data tracking from third-party services/SDKs before a user has given explicit consent. This would otherwise be a breach of data protection regulations, which can result in heavy fines.

Initialize the SDK

Initialize only when the app is in the foreground

Call initialize() / configure() once the app becomes active — not from Application.onCreate() (Android) or application(_:didFinishLaunchingWithOptions:) (iOS), since those also fire on background/OS-triggered launches (push, boot, scheduled jobs), which don’t reflect real user sessions. See the guarded pattern below.

You can initialize the SDK either for a configuration by using the SettingsID, or only for a specific geolocation by using the location’s RulesetID.

Where to find your RulesetID or SettingsID?

To find the RulesetID, navigate to Geolocation Rulesets and select the Implementation tab on the ruleset you want to use:

To find the SettingsID, open the configuration you want to use and navigate to Configuration. The SettingsID is in the header breadcrumbs:

Initialize the SDK only once!

The SDK should only be initialized once per app lifecycle. Do not initialize more than once.

Initialize the SDK with a SettingsID

  1. Import Usercentrics, configure your options and call the init method of the SDK:

// In your App struct — do NOT call this from
// application(_:didFinishLaunchingWithOptions:)
import SwiftUI
import Usercentrics

@main
struct MyApp: App {
    @Environment(\.scenePhase) private var scenePhase
    static var didInitialize = false

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .onChange(of: scenePhase) { newPhase in
            guard newPhase == .active, !Self.didInitialize else { return }
            Self.didInitialize = true

            let options = UsercentricsOptions(settingsId: <SettingsID>)
            UsercentricsCore.configure(options: options)
        }
    }
}

UIKit

Without SwiftUI, call initialize() from sceneDidBecomeActive(_:) (or applicationDidBecomeActive(_:) if not using scenes) behind the same one-shot guard, instead of didFinishLaunchingWithOptions.

Requires the lifecycle-process dependency

This snippet uses ProcessLifecycleOwner, which needs androidx.lifecycle:lifecycle-process on your app’s classpath. Add it to your app’s build.gradle(.kts) if it isn’t already there:

implementation("androidx.lifecycle:lifecycle-process:<latest_version>")

// Register on Application.onCreate() — the observer fires on the
// first genuine foreground start, not on process creation
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import com.usercentrics.sdk.*
import java.util.concurrent.atomic.AtomicBoolean

class MyApplication : Application() {
    private val didInitialize = AtomicBoolean(false)

    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onStart(owner: LifecycleOwner) {
                if (didInitialize.compareAndSet(false, true)) {
                    val options = UsercentricsOptions(settingsId = <SettingsID>)
                    Usercentrics.initialize(this@MyApplication, options)
                }
            }
        })
    }
}
// e.g place this inside the [initState] of the Entry Point Widget
import 'package:usercentrics_sdk/usercentrics_sdk.dart';

Usercentrics.initialize(
    settingsId: <SettingsID>,
);
// On your App entrypoint
import { Usercentrics, UsercentricsOptions } from '@usercentrics/react-native-sdk';

// React hooks
useEffect(() => {
    let options = new UsercentricsOptions(<SettingsID>);
    Usercentrics.configure(options);
}, []);

// Or via constructor
constructor(props: any) {
    super(props)

    let options = new UsercentricsOptions(<SettingsID>)
    Usercentrics.configure(options)
}

If you are using Unity, there are two ways to initialize the SDK. Choose the one that best fits your needs:

  • Auto initialization:

    • When using this option, the SDK initializes when the scene starts, and the banner is shown immediately afterward.

    • Only supports using the Usercentrics UI (customizable in the Usercentrics Admin Interface).

    • Enable this option in the Inspector tab, under AutoInitialize. After that, you can skip the rest of this chapter and continue with the Handle consent chapter to finish the integration.

  • Programmatic initialization:

    • You have more control over when to show the banner.

    • You can create your own banner.

using Unity.Usercentrics;

  1. Initialize the SDK when the consent status is ready.

Wait until the consent status is ready

Make sure to not use any SDK methods before the consent status is ready. Not doing so could lead to a crash, as methods called when the SDK has not finished initializing will return an exception.

Use isReady to fetch the latest consent status (see UsercentricsReadyStatus in the UsercentricsCore API page). This status will let you know if you need to show the banner to collect consent or only apply the already collected consent.

import Usercentrics

UsercentricsCore.isReady { [weak self] status in
    guard let self = self else { return }
    if status.shouldCollectConsent {
        // Show banner to collect consent
    } else {
        // Apply consent with status.consents
    }
} onFailure: { error in 
    // Handle non-localized error
}

Use isReady to fetch the latest consent status (see UsercentricsReadyStatus in the UsercentricsCore API page). This status will let you know if you need to show the banner to collect consent or only apply the already collected consent.

import com.usercentrics.sdk.*
Usercentrics.isReady({ status ->
    if (status.shouldCollectConsent) {
        // Display banner to collect consent
    } else {
        // Apply consent with status.consents
    }
}, { error ->
    // Handle non-localized error
})

See UsercentricsReadyStatus in the UsercentricsCore API page. This status will let you know if you need to show the banner to collect consent or only apply the already collected consent.

import 'package:usercentrics_sdk/usercentrics_sdk.dart';
try {
    final status = await Usercentrics.status;
    if (status.shouldCollectConsent) {
        // Show banner to collect consent
    } else {
        // Apply consent with status.consents
    }
} catch (error) {
    // Handle non-localized error
}

See UsercentricsReadyStatus in the UsercentricsCore API page. This status will let you know if you need to show the banner to collect consent or only apply the already collected consent.

import { Usercentrics } from '@usercentrics/react-native-sdk';
try {
    const status = await Usercentrics.status();
    if (status.shouldCollectConsent) {
        // Show banner to collect consent
    } else {
        // Apply consent with status.consents
    }
} catch(error) {
    // Handle error
}

On scene start, call Initialize() from a Usercentrics instance. On success, evaluate status.shouldCollectConsent.

Usercentrics.Instance.Initialize((status) => {
    if (status.shouldCollectConsent) 
    { 
        // Collect Consent
    }
    else
    {
        // Apply Consent with status.consents
    }
},(errorMessage) => {
    // Failure: Returns non-localized error
});    

To see how to display the banner, read Display the banner.

If the initialization fails

If the first init failed you can use initialize() again to clean all local storage and release the initialized instance. Make sure you validate the expected behavior.

Switching SettingsIDs

If you need to switch SettingsIDs during runtime, just reinitialize the SDK with the new SettingsID. This will automatically trigger a reset(), and initialize the new configuration.

Initialize the SDK with a RulesetID

  1. Import Usercentrics, configure your options and call the init method of the SDK:

// In your App struct — do NOT call this from
// application(_:didFinishLaunchingWithOptions:)
import SwiftUI
import Usercentrics

@main
struct MyApp: App {
    @Environment(\.scenePhase) private var scenePhase
    static var didInitialize = false

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .onChange(of: scenePhase) { newPhase in
            guard newPhase == .active, !Self.didInitialize else { return }
            Self.didInitialize = true

            let options = UsercentricsOptions()
            options.ruleSetId = "<RulesetID>"
            UsercentricsCore.configure(options: options)
        }
    }
}

UIKit

Without SwiftUI, call initialize() from sceneDidBecomeActive(_:) (or applicationDidBecomeActive(_:) if not using scenes) behind the same one-shot guard, instead of didFinishLaunchingWithOptions.

Requires the lifecycle-process dependency

This snippet uses ProcessLifecycleOwner, which needs androidx.lifecycle:lifecycle-process on your app’s classpath. Add it to your app’s build.gradle(.kts) if it isn’t already there:

implementation("androidx.lifecycle:lifecycle-process:<latest_version>")

// Register on Application.onCreate() — the observer fires on the
// first genuine foreground start, not on process creation
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import com.usercentrics.sdk.*
import java.util.concurrent.atomic.AtomicBoolean

class MyApplication : Application() {
    private val didInitialize = AtomicBoolean(false)

    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onStart(owner: LifecycleOwner) {
                if (didInitialize.compareAndSet(false, true)) {
                    val options = UsercentricsOptions(ruleSetId = "<RulesetID>")
                    Usercentrics.initialize(this@MyApplication, options)
                }
            }
        })
    }
}
// e.g place this inside the [initState] of the Entry Point Widget
import 'package:usercentrics_sdk/usercentrics_sdk.dart';

Usercentrics.initialize(
    ruleSetId: "<RulesetID>"
);
// On your App entrypoint
import { Usercentrics, UsercentricsOptions } from '@usercentrics/react-native-sdk';

// React hooks
useEffect(() => {
    let options: UsercentricsOptions = { ruleSetId: "<RulesetID>" };
    Usercentrics.configure(options);
}, []);

// Or via constructor
constructor(props: any) {
    super(props)

    let options: UsercentricsOptions = { ruleSetId: "<RulesetID>" };
    Usercentrics.configure(options)
}

If you are using Unity, there are two ways to initialize the SDK. Choose the one that best fits your needs:

  • Auto initialization:

    • When using this option, the SDK initializes when the scene starts, and the banner is shown immediately afterward.

    • Only supports using the Usercentrics UI (customizable in the Usercentrics Admin Interface).

    • Enable this option in the Inspector tab, under AutoInitialize. After that, you can skip the rest of this chapter and continue with the Handle consent chapter to finish the integration.

  • Programmatic initialization:

    • You have more control over when to show the banner.

    • You can create your own banner.

Import Usercentrics to the scene:

using Unity.Usercentrics;

  1. Initialize the SDK when the consent status is ready.

Wait until the consent status is ready

Make sure to not use any SDK methods before the consent status is ready. Not doing so could lead to a crash, as methods called when the SDK has not finished initializing will return an exception.

Use isReady to get the geolocationRuleset (see GeolocationRuleset in the UsercentricsCore API page). This object will let you know if the banner is required according to the configurations and the user's location.

import Usercentrics
UsercentricsCore.isReady { [weak self] status in
    guard let self = self else { return }
    if status.geolocationRuleset != null && status.geolocationRuleset.bannerRequiredAtLocation == false {
        // banner is not required at this location
        return
    }
    if status.shouldCollectConsent {
        // Show banner to collect consent
    } else {
        // Apply consent with status.consents
    }
} onFailure: { error in 
    // Handle non-localized error
}

Use isReady to get the geolocationRuleset (see GeolocationRuleset in the UsercentricsCore API page). This object will let you know if the banner is required according to the configurations and the user's location.

import com.usercentrics.sdk.*
Usercentrics.isReady({ status ->
    if (status.geolocationRuleset != null && status.geolocationRuleset?.bannerRequiredAtLocation == false) {
        // banner is not required at this location
        return@isReady
    }
    if (status.shouldCollectConsent) {
        // Show banner to collect consent
    } else {
        // Apply consent with status.consents
    }
}, { error ->
    // Handle non-localized error
})
import 'package:usercentrics_sdk/usercentrics_sdk.dart';

try {
    final status = await Usercentrics.status;

    if (status.geolocationRuleset != null && status.geolocationRuleset?.bannerRequiredAtLocation == false) {
        // banner is not required at this location
        return;
    }

    if (status.shouldCollectConsent) {
        // Show banner to collect consent
    } else {
        // Apply consent with status.consents
    }
} catch (error) {
    // Handle non-localized error
}
import { Usercentrics } from '@usercentrics/react-native-sdk';

try {
    const status = await Usercentrics.status();

    if (status.geolocationRuleset != null && status.geolocationRuleset?.bannerRequiredAtLocation == false) {
        // banner is not required at this location
        return
    }

    if (status.shouldCollectConsent) {
        // Show banner to collect consent
    } else {
        // Apply consent with status.consents
    }
} catch(error) {
    // Handle error
}
Usercentrics.Instance.Initialize((status) => {

    if (status.geolocationRuleset.bannerRequiredAtLocation == false)
    {
        return;
    }

    if (status.shouldCollectConsent)
    { 
        // Collect Consent
    } 
    else
    {
        // Apply Consent with status.consents
    }

},(errorMessage) => {
    // Failure: Returns non-localized error
});

Read the Display banner page to learn how to show the banner to collect consent.

To see how to display the banner, read Display the banner.

If the initialization fails (e.g. due to connection issues)

If the first init failed you can use initialize() again to clean all local storage and release the initialized instance. Make sure you validate the expected behavior. We recommend to treat this as if the user did not give consent.

Switching RulesetIDs

If you need to switch RulesetIDs during runtime, just reinitialize the SDK with the new RulesetID. This will automatically trigger a reset(), and initialize the new configuration.

Configure the SDK

Select your device options

In addition to the SettingsID, you may also configure the following options to control different behaviors at a device-level:

Property

Type

Notes

settingsID

String

A Usercentrics generated ID, used to identify a unique CMP configuration.

rulesetID

String

A Usercentrics generated ID, used to identify a bundle of CMP configurations to be used depending on the user's location.

defaultLanguage

String

Selected based on our language selection hierarchy. This property defines the language used to render the banner. e.g. "en", "de", "fr".

version

String

To freeze the configuration version shown to your users, you may pass a specific version here. You may find an overview of all versions in your Configuration Dashboard under Configuration > History > Settings History > Version (Column) or Implementation > Script Tag > Version History. e.g. "3.0.4". Passing "latest" (default) will fetch the latest version of your CMP configuration. Passing "preview" will fetch the latest draft of your CMP configuration.

timeoutMillis

Int

Timeout for network requests in milliseconds. We do NOT recommend overwriting this field unless absolutely necessary or for debugging reasons, as well as using any values under 5,000 ms (5s). Default is 10,000 ms (10s).

loggerLevel

Enum

Provides a set of logs for operations being executed in the SDK.

  • debug: includes every other level

  • warning: non-problematic operations

  • error: relevant logs to any blocking problems

  • none (default)

consentMediation

Bool

Enable Consent Mediation, an automated way to pass consent to third-party frameworks.

initTimeoutMillis

Int

Timeout for SDK initialization. Minimum value is 5,000ms (5s) and the Default value is 10,000 ms (10s).

[Mobile games] debugMode

Bool

Get all errors, warning and logs when running the SDK.

[Mobile games - Android] Disable System Back Button

Bool

Toggles the system back button of the device.

[Mobile games - Android] Status Bar Color

String

Edit the color (using hexadecimal string) of the status bar when the banner is displayed.

Select your language hierarchy

The SDK uses the following hierarchy, when deciding which language to load on init to render the banner (e.g. "en", "de", "fr".):

LanguageHierarchy

On first init, Default Language will have first priority, then Device language and finally a hard default to the first language available in your configuration. Once a language has been selected, it will be stored. Any following SDK initializations will use the Stored Language.

Notes:

  1. To be supported, a language needs to be added and set as visible in the Admin Interface, under Configuration - Setup - Language Settings.

  2. This value will only be checked during the first SDK initialized. Afterwards, the stored languages will be used.

  3. If a user explicitly selects a new language in the Usercentrics UI, or the language is changed programmatically after init, the stored languages will be updated and take priority in the future.

TCF special cases to bear in mind

Update your app when a new TCF version is released

The IAB sets a deadline for each new TCF version, and CMPs must implement it in apps by then. This includes the new texts and their translations, which come from the IAB's Global Vendor List (GVL).

The new version reaches your users only when they run an app version that includes the updated Usercentrics SDK. To stay compliant:

  1. Update to the Usercentrics SDK version that supports the new TCF version.

  2. Release the new app version in the app stores.

  3. Make sure your users install it before the IAB deadline. If you can, use a forced or minimum-version update, because users who postpone the update keep the old banner.

We announce each new TCF version and its deadline in the release notes.

When implementing the TCF Framework, it's important to note that Usercentrics does not manage all the translations. This responsibility falls to the IAB, the institution that owns the Framework.

If a language is chosen in the Admin Interface that is not supported by the IAB, it will not appear in the language selector popup.

To ensure a seamless integration, verify your desired language against the IAB's official list of supported languages at IABs official list before launching the Banner in production. This proactive step is crucial for maintaining compliance and ensuring a smooth user experience.

⚠️ Dialects are supported and automatically used.

If the language you pick in the Admin Interface has different dialects and the IAB doesn't support them, we'll automatically select the main dialect. This way, users won't miss out on seeing their language choice.