Skip to content

California Consumer Privacy Act (CCPA)

Unity Support

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

Data Source

In order to build your own CCPA compliant CMP, the SDK provides 4 data sources:

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

// General UI content for CCPA can be found in `settings.ccpaui`
val settings = usercentrics.getSettings()
val categories = usercentrics.getCategories()
val services = usercentrics.getServices()
val ccpaData = usercentrics.getUSPData()

// General UI content for CCPA can be found in `settings.ccpaui`
var settings = Usercentrics.Instance.GetSettings();
var categories = Usercentrics.Instance.GetCategories();
var services = Usercentrics.Instance.GetServices();
var ccpaData = Usercentrics.Instance.GetUSPData();

// General UI content for CCPA can be found in `settings.ccpaui`

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.

Depending on your design, you could have different action buttons or toggles but at the end of the day, CCPA is a global opted out framework. That means two things:

  1. You only have to save/read one flag for all the consents.
  2. The consent is given by default and the user have to opt out to reject the consent explicitly.

We offer one simplified method to interact with CCPA:

usercentrics.saveOptOutForCCPA(isOptedOut: isOptedOut, consentType: .explicit) {
    // Handle successful request. In most cases, dismiss the CMP view and update your services.
} onFailure = { error in
    // Handle non-localized error
}

Consent Type

We require that you declare how consent is collected. By an explicit action of the user or implicitly. (Please consult your legal adviser when using implicit consent)

usercentrics.saveOptOutForCCPA(isOptedOut, ConsentType.EXPLICIT, callback = {
    // Handle successful request. In most cases, dismiss the CMP view and update your services.
}, onFailure = { error ->
    // Handle non-localized error
})

Consent Type

We require that you declare how consent is collected. By an explicit action of the user or implicitly. (Please consult your legal adviser when using implicit consent)

Usercentrics.Instance.SaveOptOutForCCPA(
    isOptedOut,
    () =>
    {
        // Handle successful request. In most cases, dismiss the CMP view and update your services.
    },
    (errorMessage) =>
    {
        // Handle non-localized error
    }
);

Now that you have collected your user's consent, it is essential that you enforce these choices to your third-party frameworks.

In order to match the services provided in the Admin Interface and the frameworks running on your app, we provide a templateID.

TemplateID

This templateID is unique and can be used to apply consent in a function like this:

func updateServices() {
    guard let services = self.usercentrics.getServices() else { return }
    for service in services {
        switch service.id { // TemplateID in Admin Interface
        case "S1_9Vsuj-Q": // Google Ads Template ID
            GoogleAdsFramework.enabled = service.consent.status
        case "XX-XxX-xx": // Service Template ID
            Framework.enabled = service.consent.status
        case "x-XXXxXx": // Service Template ID
            Framework.enabled = service.consent.status
        default: break
        }
    }
}
fun updateServices() {
    val services = usercentrics.getServices()
    for (service in services) {
        if(service.id == "XxxXxXx") { // Template ID for "Google Ads" in Admin Interface
            GoogleAdsFramework.enabled = service.consent.status
        } else if(service.id == "XxXxxXXx") { // Template ID for Service in Admin Interface
            Framework.enabled = service.consent.status
        } else if(service.id == "XxXxxXXx") { // Template ID for Service in Admin Interface
            Framework.enabled = service.consent.status
        }
    }
}
private const string ADS_FRAMEWORK_TEMPLATE_ID = "XxxXXxXxX";
private const string ANALYTICS_FRAMEWORK_TEMPLATE_ID = "YYyyYyYYY";

public static void UpdateServices()
{
    foreach (var service in Usercentrics.Instance.GetServices())
    {
        switch (service.id)
        {
            case ADS_FRAMEWORK_TEMPLATE_ID:
                GoogleAdsFramework.Enabled = service.consent.status;
                break;
            case ANALYTICS_FRAMEWORK_TEMPLATE_ID:
                AnalyticsFramework.Enabled = service.consent.status;
                break;
            default:
                break;
        }
    }
}

This function needs to be called right after any of the saving consent functions has concluded.

usercentrics.saveOptOutForCCPA(isOptedOut: isOptedOut, consentType: .explicit) {
    //Handle post-consent tasks e.g. Dismiss CMP

    updateServices()
} onFailure = { error in
    // Handle non-localized error
}
usercentrics.saveOptOutForCCPA(isOptedOut, ConsentType.EXPLICIT, callback = {
    //Handle post-consent tasks e.g. Dismiss CMP

    updateServices()
}, onFailure = { error ->
    // Handle non-localized error
})
Usercentrics.Instance.SaveOptOutForCCPA(
    isOptedOut,
    () =>
    {
        //Handle post-consent tasks e.g. Dismiss CMP

        UpdateServices()
    },
    (errorMessage) =>
    {
        // Handle non-localized error
    }
);

Always apply consent first

On every App Launches, once consent has been collected, you need to directly call this function after initializing the SDK. See Updating Consent.

As your App evolves throughout time, so will the frameworks running on it. Therefore, you will need to update consent by reshowing the CMP whenever there are changes or updates to your terms of service.

For this, we provide initialLayer, which you can use to know if you need to show your custom CMP or just apply consent. See:

usercentrics.initialize { initialValues in
    switch initialView.initialLayer {
    case .firstLayer:
        self.presentCustomCMP()
    case .none:
        self.updateConsent()
    }
} onFailure: { error in
    // Handle non-localized error
}
usercentrics.initialize(
    callback = { initialValues ->
        when (initialValues.initialLayer) {
            InitialView.FIRST_LAYER -> presentCustomCMP()
            InitialView.NONE -> updateConsents()
        }
    }, onFailure = { error ->
        // Handle non-localized error
    }
)

For this, we provide the showCMP flag, which you can use to know if you need to show the CMP or just apply consent. See:

Usercentrics.Instance.Initialize((showCMP) =>
{
   if (showCMP)
   {
       PresentCMP();
   }
   else
   {
       UpdateServices();
   }
},
(errorMessage) =>
{
    // Handle non-localized error
});

Collecting Consent for the First Time

The first time you initialize the SDK, initialLayer will also return firstLayer, so the above example will handle all cases of presenting the CMP when consent needs to be collected or updated.

Continue to common functions

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