Documentation Index

Fetch the complete documentation index at: https://usercentrics.document360.io/llms.txt

Use this file to discover all available pages before exploring further.

Manage core consent

Prev Next

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

Now that you have collected consent, let's make sure to respect the user's choices by applying consent to each SDK.

IMPORTANT: Please review EVERY vendor's documentation to understand how each SDK expects consent to be passed.

DO NOT assume consent is passed automatically to every SDK. Even if you are using the TCF standard or our Consent Mediation feature, please test and verify that consent is reaching the target SDKs.

Consent data in the userResponse object

The collected consents are in the userResponse object provided in the callback of UsercentricsBanner.showLayer().

Properties

Type

Notes

consents

[UsercentricsServiceConsent]

List of the user's consent choices needed to apply consent.

userInteraction

Enum

  • AcceptAll: User accepted all services.

  • DenyAll: User denied all service.

  • Granular: User gave a granular choice,

  • No Interaction: User dismissed the Banner with no response.

controllerId

String

A Usercentrics generated ID, used to identify a specific user.
This value is required when using Cross-Device Consent Sharing.

You will use this information to apply the user's privacy choices to the third-party SDKs on your app.
The next sections describe when and how to apply consent.

When should you apply consent?

After consent is given by the user it can be applied for the intended purposes.

After collecting consent

Consent will only change if the banner is shown to the user and an action is taken. When using the UsercentricsUI, the callback will return the new values, and you will need to use it to apply consent:

The first time you launch the app with the Usercentrics SDK, no consent will have been collected and status.shouldCollectConsent returned in isReady will be TRUE, letting you know that you should collect consent by showing the banner. Once a user has responded, a userResponse will be returned on the banner callback, which will contain the consent object.

let banner = UsercentricsBanner()
banner.showFirstLayer(hostView: self) { userResponse in
    self.applyConsent(with: userResponse.consents)
}
val banner = UsercentricsBanner(<Context>)
banner.showFirstLayer() { userResponse ->
    applyConsent(userResponse?.consents)
}
final userResponse = await Usercentrics.showFirstLayer();
applyConsent(userResponse?.consents);
final userResponse = await Usercentrics.showFirstLayer();
applyConsent(userResponse.consents);

Usercentrics.Instance.ShowFirstLayer(<UsercentricsLayout>, (userResponse) => {
    applyConsent(userResponse.consents);
});

In a similar manner, if you are building your own UI, you will need to apply consent after any consent storage action is triggered:

let consents = UsercentricsCore.shared.acceptAll(consentType: .explicit_) // also applies for "deny" and "save"
self.applyConsent(with: consents)
val consents = Usercentrics.instance.acceptAll(consentType = UsercentricsConsentType.EXPLICIT) // also applies for "deny" and "save"
applyConsent(consents)
final consents = Usercentrics.acceptAll(consentType: UsercentricsConsentType.explicit); // also applies for "deny" and "save"
applyConsent(consents);
const consents = Usercentrics.acceptAll(UsercentricsConsentType.explicit); // also applies for "deny" and "save"
applyConsent(consents);

After a new app launch

In any future initialization after the first one, you will already have a consent status and you will only need to apply it. Make sure to do this as early as possible.

UsercentricsCore.isReady { status in
    if status.shouldCollectConsent {
        // Collect Consent
    } else {
        self.applyConsent(with: status.consents)
    }
} onFailure: { error in 
    // Handle non-localized error
}
Usercentrics.isReady({ status ->
    if (status.shouldCollectConsent) {
        // Collect Consent
    } else {
        applyConsent(status.consents)
    }
},{ error ->
    // Handle non-localized error
})
try {
  final status = await Usercentrics.status;

  if (status.shouldCollectConsent) {
    //Collect Consent
  } else {
    applyConsent(status.consents);
  }
} catch (error) {
  // Handle non-localized error
}
import { Usercentrics } from '@usercentrics/react-native-sdk';

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

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

Getting consent on demand

You may also call UsercentricsCore.shared.getConsents() to get the consent directly, but make sure to do so after the isReady callback has been triggered.

How to apply consent?

First, match the third-party technologies declared in your configuration with the SDKs running in your app. SDKs that access and process user and/or device data are only allowed to do so if the user has given explicit consent. To be compliant, review every SDK in your app, including:

The following sections describe how to match these with the respective SDKs.

Data Processing Services (DPS)

How to match a DPS with an SDK?

Every data processing service (e.g. Firebase, Unity Ads, Adjust, Applovin, Vungle) has a unique identifier called templateID. This ID is shown in the Admin Interface under Service Settings - Data Processing Services - expand the service - Template ID.

You will use the Template ID of each declared service to match them with their respective SDK.

This process is different for SDKs that have a consent API, from SDKs that don’t have any consent API. The following sections describe how to apply the consent in each of these cases.

Applying consent for Unity

In the case of the Unity SDK, consent for non-IAB (non-TCF) vendors MUST be applied programmatically.

Applying consent to SDKs with a consent API

SDKs that support data privacy compliance will provide an API to set the user's consent status. The API and it's behavior will be documented by the SDK's provider.

Examples:

Regulation-dedicated APIs

Please note that most APIs are dedicated for a specific regulation. e.g. GDPR for Europe, CCPA/CPRA for US/California, COPPA for children protection, etc. Make sure to review the documentation and apply the consent for the correct regulation.

To apply consent to these SDKs, identify the target SDK and implement the consent API as follows:

func applyConsent(with consents: [UsercentricsServiceConsent]) {
    for service in consents {
        switch service.templateId {
        case "diWdt4yLB": // Google Analytics for Firebase Template ID

            // Google Firebase Consent Mode API
            let firebaseConsentStatus = service.status ? .granted : .denied
            Analytics.setConsent([
                .analyticsStorage: firebaseConsentStatus
                .adStorage: firebaseConsentStatus
            ])
            initializeFirebase()

        case "x-XXXxXx": // Other Service Template ID
            // Pass consent to framework with service.status
        default:
            // Log a warning if a service was not caught or do nothing
        }
    }
}
fun applyConsent(consents: List<UsercentricsServiceConsent>?) {
    consents?.forEach { service ->
        when (service.templateId) {
            "diWdt4yLB" -> { // Google Analytics for Firebase Template ID

                // Google Firebase Consent Mode API
                val firebaseConsentStatus = if (service.status) ConsentStatus.GRANTED else ConsentStatus.DENIED
                Firebase.analytics.setConsent {
                    analyticsStorage(firebaseConsentStatus)
                    adStorage(firebaseConsentStatus)
                }
                initializeFirebase()    

            }
            // Other Service Template ID
            "x-XXXxXx" -> {
                // Initialize or pass consent to framework with service.status
            }
            else -> {
                // Log a warning if a service was not caught or do nothing
            }
        }
    }
}
void applyConsent(List<UsercentricsServiceConsent>? consents) {
  consents?.forEach((service) {
    switch (service.templateId) {
      case "diWdt4yLB": // Google Analytics for Firebase Template ID

        // Google Firebase Consent Mode API
        applyConsentToFirebase(service.status) // See iOS and Android examples
        initializeFirebase()    

        break;
      case "x-XXXxXx": // Other Service Template ID
        // Initialize or pass consent to framework with service.status
        break;
      default:
        // Log a warning if a service was not caught or do nothing
    }
  });
}
import { UsercentricsServiceConsent } from '@usercentrics/react-native-sdk';

const applyConsents = (consents: [UsercentricsServiceConsent]) => {
    consents.forEach(service => {
        switch (service.templateId) {
            case "diWdt4yLB": // Google Analytics for Firebase Template ID

                // Google Firebase Consent Mode API
                applyConsentToFirebase(service.status) // See iOS and Android examples
                initializeFirebase()
                break;

            // Other Service Template ID
            case "x-XXXxXx":
                // Initialize or pass consent to framework with service.status
                break;

            default:
                // Log a warning if a service was not caught or do nothing
        }
    });
}
private void applyConsent(List<UsercentricsServiceConsent> consents){
    foreach (var serviceConsent in consents) {
        switch (serviceConsent.templateId) {
            case "hpb62D82I": // Unity Ads Template ID
                // UnityAdsConsentAPI.Enabled = service.consent.status;
                break;
            case "YYyyYyYYY": // Other SDK Template ID
                // Pass consent to framework with service.status
                break;
            default:
                // Log a warning if a service was not caught or do nothing
                break;
        }
    }
}

Not all APIs are created equal

Please make sure you read through each documentation, as many providers might require other steps to fully be complaint.

Applying consent to SDKs without a consent API

For SDKs that track user/device data and do not offer a consent API, the only solution is to not initialize those SDKs, when a user did not provide consent.

func applyConsent(with consents: [UsercentricsServiceConsent]) {
    for service in consents {
        switch service.templateId {
        case "x-XXXxXx": // Template ID

            // Only initialize an SDK if consent has been given
            if service.status { initializeSDK() }

        case "x-xXX-Xx": // Other Service Template ID
            //Initialize framework based on service.status
        default:
            // Log a warning if a service was not caught or do nothing
        }
    }
}
fun applyConsent(consents: List<UsercentricsServiceConsent>?) {
    consents?.forEach { service ->
        when (service.templateId) {
            "x-XXXxXx" -> { // Template ID
                // Only initialize an SDK if consent has been given
                if (service.status) {
                    initializeSDK()
                }
            }
            "x-xXX-Xx" -> { // Other Template ID
                //Initialize framework based on service.status
            }
            else -> {
                // Log a warning if a service was not caught or do nothing
            }
        }
    }
}
void applyConsent(List<UsercentricsServiceConsent>? consents) {
  consents?.forEach((service) {
    switch (service.templateId) {
      case "x-XXXxXx": // Template ID
        // Only initialize an SDK if consent has been given
        if (service.status) {
          initializeFirebase();
        }
        break;

      case "x-xXX-Xx": // Other Template ID
        // Initialize framework based on service.status
        break;

      default:
        // Log a warning if a service was not caught or do nothing
    }
  });
}
import { UsercentricsServiceConsent } from '@usercentrics/react-native-sdk';

const applyConsents = (consents: [UsercentricsServiceConsent]) => {
    consents.forEach(service => {
        switch (service.templateId) {
            case "x-XXXxXx": // Template ID
                // Only initialize an SDK if consent has been given
                if (service.status) {
                    // initializeSDK();
                }
                break;

            // Other Service Template ID
            case "x-xXX-Xx":
                // Initialize framework based on service.status
                break;

            default:
                // Log a warning if a service was not caught or do nothing
        }
    });
}
private void applyConsent(List<UsercentricsServiceConsent> consents){
    foreach (var serviceConsent in consents) {
        switch (serviceConsent.templateId) {
            case "x-XXXxXx": // Template ID
                // Only initialize an SDK if consent has been given
                if (service.status) { initializeSDK() }
                break;
            case "YYyyYyYYY": // Other SDK Template ID
                //Initialize framework based on service.status
                break;
            default:
                // Log a warning if a service was not caught or do nothing
                break;
        }
    }
}

Vendors (TCF 2.2)

When using third-party services that are certified as TCF Vendors, you will need to declare these services via the Global Vendor List (GVL) tab, in the Service Settings section of your TCF configuration.

If you have selected your TCF Vendors in the GVL and published the changes, when a user provides consent the SDK will generate an encoded string called TC String with the consent for these vendors according to the TCF 2.2 standard.

TC String

As specified by the IAB, the collected consent for IAB Vendors will be encoded into a TCString and stored locally in NSUserDefaults(iOS) or SharedPreferences(Android).

In most cases, the Vendor SDK might automatically pull the TCString, and apply consent to itself automatically. In case the vendor SDK requires you to pass the TCString programmatically, you may use:

UsercentricsCore.shared.getTCFData() { tcfData in
    let tcString = tcfData.tcString
}
Usercentrics.instance.getTCFData { tcfData ->
    val tcString = tcfData.tcString
}
Usercentrics.getTCString();
import { Usercentrics } from '@usercentrics/react-native-sdk';

const tcString = await Usercentrics.getTCFString();
Usercentrics.Instance.GetTCFData((tcfData) => {
    var tcString = tcfData.tcString;
});

Alternatively, you can also find it directly in memory with their specific Key.

let defaults = UserDefaults.standard
let tcString = defaults.string(forKey: "IABTCF_TCString")
val preferences = PreferenceManager.getDefaultSharedPreferences(this)
val tcString = preferences.getString("IABTCF_TCString")