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
.
Saving Consent¶
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
}
);
Applying Consent¶
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
.
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.
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:
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 |