Skip to content

General Data Protection Regulation (GDPR)

Unity Support

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

Data Source

In order to build your own GDPR compliant CMP, the SDK provides 3 data sources:

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

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

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

// General UI content for GDPR can be found in `settings.ui`

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 will have different action buttons. The following 3 functions can cover all scenarios when collecting consent:

Accept All Services

usercentrics.acceptAllServices(consentType: .explicit) {
    // Handle successful request. In most cases, dismiss the CMP view and update your services.
} onFailure = { error in
    // Handle non-localized error
}
usercentrics.acceptAllServices(UCConsentType.EXPLICIT, callback = {
    // Handle successful request. In most cases, dismiss the CMP view and update your services.
}, onFailure = { error ->
    // Handle non-localized error
})
Usercentrics.Instance.AcceptAllServices(
    ()=>
    {
        // Handle successful request. In most cases, dismiss the CMP view and update your services.
    },
    (errorMessage) =>
    {
        // Handle non-localized error
    }
);

Deny All Services

usercentrics.denyAllServices(consentType: .explicit) {
    // Handle successful request. In most cases, dismiss the CMP view and update your services.
} onFailure = { error in
    // Handle non-localized error
}
usercentrics.denyAllServices(UCConsentType.EXPLICIT, callback = {
    // Handle successful request. In most cases, dismiss the CMP view and update your services.
}, onFailure = { error ->
    // Handle non-localized error
})
Usercentrics.Instance.DenyAllServices(
    ()=>
    {
        // Handle successful request. In most cases, dismiss the CMP view and update your services.
    },
    (errorMessage) =>
    {
        // Handle non-localized error
    }
);

Save Services

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

var decisions: [UserDecision] = []
decisions.append(UserDecision(serviceId: <ServiceTemplateID>, status: true))
decisions.append(UserDecision(serviceId: <ServiceTemplateID>, status: false))
decisions.append(UserDecision(serviceId: <ServiceTemplateID>, status: true))

usercentrics.updateServices(decisions: decisions, 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

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

val decisions = mutableListOf<UserDecision>()

decisions.add(UserDecision(serviceId = "xxx-xxXX", status = true))
decisions.add(UserDecision(serviceId = "-xxxxXXx", status = false))
decisions.add(UserDecision(serviceId = "XXXxxxxx", status = true))

usercentrics.updateServices(decisions = decisions, consentType = UCConsentType.EXPLICIT, callback = {
    // Handle successful request. In most cases, dismiss the CMP view and update your services.
}, onFailure = { error ->
    // Handle non-localized error
})
Consent Type

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

var decisions = new List<UCUserDecision>();
decisions.Add(new UCUserDecision("xxx-xxXX", true));
decisions.Add(new UCUserDecision("-xxxxXXx", false));
decisions.Add(new UCUserDecision("XXXxxxxx", true));

Usercentrics.Instance.UpdateServices(
    decisions,
    ()=>
    {
        // 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.acceptAllServices(consentType: .explicit) {
    //Handle post-consent tasks e.g. Dismiss CMP

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

    updateServices()
}, onFailure = { error ->
    // Handle non-localized error
})
Usercentrics.Instance.AcceptAllServices(
    ()=>
    {
        //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
}

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(
    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

Content Mapping

There is a lot of content needed to build a CMP, for this reason we have provided this mapping table, to help you navigate our Data Source:

image image

CMP Component SDK Property
1. Title settings.ui.firstLayer.title
2. Description settings.ui.firstLayer.layerDescription.defaultDescription
3. Short Description settings.ui.firstLayer.layerDescription.shortDescription
4. Read More settings.ui.labels.general.readMore
5. Privacy Policy Text settings.ui.links.privacyPolicy.label
6. Privacy Policy URL settings.ui.links.privacyPolicy.url
7. Imprint Text settings.ui.links.imprint.label
8. Imprint URL settings.ui.links.imprint.url
9. Language Selected settings.ui.language.selected
10. Languages Available settings.ui.language.available
11. Categories Tab settings.ui.secondLayer.tabs.categories.label
12. Services Tab settings.ui.secondLayer.tabs.services.label
13. Accept All settings.ui.buttons.acceptAll.label
14. Deny All settings.ui.buttons.denyAll.label
15. Save Services settings.ui.buttons.save.label
Category Component SDK Property
16. Category Name category.label
17. Category Description category.categoryDescription
Services Component SDK Property
18. Service Name service.name
19. Service Description Title settings.ui.labels.service.descriptionTitle
20. Service Description service.serviceDescription
21. Processing Company Title settings.ui.labels.service.processing.CompanyTitle
22. Processing Company service.processingCompany.name + service.processingCompany.address
23. Data Purposes Title settings.ui.labels.service.dataPurposes.title
24. Data Purposes Description settings.ui.labels.service.dataPurposes.descriptionTitleDescription
25. Data Purposes service.dataPurposes
26. Technologies Used Title settings.ui.labels.service.technologiesUsed.title
27. Technologies Used Description settings.ui.labels.service.technologiesUsed.descriptionTitleDescription
28. Technologies Used service.technologiesUsed
29. Data Collected Title settings.ui.labels.service.dataCollected.title
30. Data Collected Description settings.ui.labels.service.dataCollected.descriptionTitleDescription
31. Data Collected service.dataCollected
32. Legal Bases Title settings.ui.labels.service.legalBasis.title
33. Legal Bases Description settings.ui.labels.service.legalBasis.descriptionTitleDescription
34. Legal Bases service.legalBasis
35. Processing Location Title settings.ui.labels.service.dataDistribution.processingLocationTitle
36. Processing Location service.dataDistribution.processingLocation
37. Retention Period Title settings.ui.labels.service.retentionPeriodTitle
38. Retention Period service.retentionPeriodDescription
39. Third Country Distribution Title settings.ui.labels.service.dataDistribution.thirdPartyCountriesTitle
40. Third Country Distribution service.dataDistribution.thirdPartyCountries
41. Data Recipients Title settings.ui.labels.service.dataRecipientsTitle
42. Data Recipients service.processingCompany.dataProtectionOfficer + service.processingCompany.name + service.processingCompany.address
43. Privacy Policy Title settings.ui.labels.service.urls.privacyPolicyTitle
44. Privacy Policy service.urls.privacyPolicy
45. Cookie Policy Title settings.ui.labels.service.urls.cookiePolicyTitle
46. Cookie Policy service.urls.cookiePolicy
47. Opt Out Link Title settings.ui.labels.service.urls.optOutPolicy
48. Opt Out Link service.urls.optOut
49. History Title settings.ui.labels.service.history.title
50. History Description settings.ui.labels.service.history.descriptionTitleDescription
51. History service.consent.history
52. History Consent Given settings.ui.labels.general.consentGiven
53. History Consent Not Given settings.ui.labels.general.consentNotGiven
54. History Explicit Consent settings.ui.labels.general.explicitLabel
55. History Implicit Consent settings.ui.labels.general.implicitLabel
56. Controller ID Title settings.ui.labels.general.controllerId
57. Controller ID settings.controllerId
58. ProcessorID Title settings.ui.labels.general.processorId
59. Processor ID service.processorId