Skip to content

Transparency & Consent Framework (TCF 2.0)

Unity Support

We currently do not support building a Custom UI for TCF 2.0 with our Unity Package. We only support TCF 2.0 with our Predefined UI.

In order to build your own TCF 2.0 compliant CMP, the SDK provides the following data sources:

IAB Data Source

let tcfData = usercentrics.getTCFData()
let tcString = usercentrics.getTCString()

let purposes = tcfData.purposes
let specialPurposes = tcfData.specialPurposes
let features = tcfData.features
let specialFeatures = tcfData.specialFeatures
let stacks = tcfData.stacks
let vendors = tcfData.vendors
val tcfData = usercentrics.getTCFData()
val tcString = usercentrics.getTCString()

val purposes = tcfData.purposes
val specialPurposes = tcfData.specialPurposes
val features = tcfData.features
val specialFeatures = tcfData.specialFeatures
val stacks = tcfData.stacks
val vendors = tcfData.vendors

Non-IAB Data Source

guard let settings: UCSettings? = usercentrics.getSettings(),
    let categories: [UCCategory]? = usercentrics.getCategories(),
    let services: [UCService]? = usercentrics.getServices() else { return }

// General UI content for TCF 2.0 can be found in `settings.tcfui`
val settings = usercentrics.getSettings()
val categories = usercentrics.getCategories()
val services = usercentrics.getServices()

// General UI content for TCF 2.0 can be found in `settings.tcfui`

Duplicate Source of Services

A Category provides a list of services under category.services. You may match services from getServices to categories with category.slug == service.categorySlug.

Set CMP ID

When building a custom CMP for TCF 2.0, it is required to have your CMP UI design certified by the IAB. Once certified, you will need to provide your CMP ID in your application as follows:

usercentrics.setCMPID(id: <CMPID>) {
    // Handle successful request. In most cases, dismiss the CMP view and update your services.
} onFailure = { error in
    // Handle non-localized error
}
usercentrics.setCMPID(<CMPID>, callback = {
    // CMP ID was successfully stored on TCString.
}, onFailure = { error ->
    // Handle non-localized error
})

Depending on your design, you will have different action buttons. The following 3 functions can cover all scenarios when collecting consent:

Accept All Services

usercentrics.acceptAllForTCF(fromLayer: <TCF_DECISION_LAYER>) {
    // Handle successful request. In most cases, dismiss the CMP view and update your services.
} onFailure: { error in
    // Handle non-localized error
}
usercentrics.acceptAllForTCF(<TCF_DECISION_LAYER>, callback = {
    // Handle successful request. In most cases, dismiss the CMP view and update your services.
}, onFailure = { error ->
    // Handle non-localized error
})

Deny All Services

usercentrics.denyAllForTCF(fromLayer: <TCF_DECISION_LAYER>) {
    // Handle successful request. In most cases, dismiss the CMP view and update your services.
} onFailure: { error in
    // Handle non-localized error
}
usercentrics.denyAllForTCF(<TCF_DECISION_LAYER>, callback = {
    // Handle successful request. In most cases, dismiss the CMP view and update your services.
}, onFailure = { error ->
    // Handle non-localized error
})

Save Services

For granular selection, you may pass specific sets of consent with an array of UserDecision.

var decisions: [TCFUserDecisions] = []
decisions.append(TCFUserDecisions(purposes: <[TCFUserDecisionOnPurpose]?>, specialFeatures: <[TCFUserDecisionOnSpecialFeature]?>, vendors: <[TCFUserDecisionOnVendor]?>), status: true))
decisions.append(TCFUserDecisions(purposes: <[TCFUserDecisionOnPurpose]?>, specialFeatures: <[TCFUserDecisionOnSpecialFeature]?>, vendors: <[TCFUserDecisionOnVendor]?>), status: false))

usercentrics.updateChoicesForTCF(decisions: decisions, fromLayer: <TCF_DECISION_LAYER>) {
    // Handle successful request. In most cases, dismiss the CMP view and update your services.
} onFailure: { ERROR in
    // Handle non-localized error
}
val decisions = mutableListOf<TCFUserDecisions>()

decisions.add(TCFUserDecisions(purposes: <[TCFUserDecisionOnPurpose]?>, specialFeatures: <[TCFUserDecisionOnSpecialFeature]?>, vendors: <[TCFUserDecisionOnVendor]?>), status = true))
decisions.add(TCFUserDecisions(purposes: <[TCFUserDecisionOnPurpose]?>, specialFeatures: <[TCFUserDecisionOnSpecialFeature]?>, vendors: <[TCFUserDecisionOnVendor]?>), status = false))

usercentrics.updateChoicesForTCF(decisions = decisions, fromLayer: <TCF_DECISION_LAYER>, callback = {
    // Handle successful request. In most cases, dismiss the CMP view and update your services.
}, onFailure = { error ->
    // Handle non-localized error
})

TCF 2.0 Decision Layer

Depending on your design, you might have 1 or 2 layers for collecting consent. It is required by the IAB, that you specify in which layer the consent was collected. For this, you may pass the corresponding enum value from TCF_DECISION_UI_LAYER.

As specified by the IAB, the consent collected will be encoded and stored locally in NSUserDefaults(iOS) or SharedPreferences(Android). You may access these values with their specific Keys, but most third-party Frameworks will have listeners to apply this consent automatically.

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

Alternatively, we have also enabled the method:

usercentrics.getTCString()
usercentrics.getTCString()
Usercentrics.Instance.GetTCString()

Additionally to the IAB Purposes, you might want to complete your consent coverage with Non-IAB Services. If this is the case, please see and implement Save Consent, Apply Consent and Update Consent to cover these cases.

Continue to common functions

To complete the implementation of your custom CMP, we offer several usability functions. Please see Common Functions