@usercentrics/react-native-sdk 2.10.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/android/build.gradle +1 -1
  3. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/RNUsercentricsModuleTest.kt +84 -123
  4. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetCMPDataMock.kt +647 -499
  5. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetTCFDataMock.kt +14 -4
  6. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/SaveDecisionsForTCFMock.kt +7 -1
  7. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/RNUsercentricsModule.kt +10 -1
  8. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/ConsentDisclosureSerializer.kt +24 -0
  9. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/TCFDataExtensions.kt +12 -4
  10. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/UserDecisionExtensions.kt +18 -1
  11. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/UsercentricsCMPDataExtensions.kt +85 -7
  12. package/ios/Extensions/TCFData+Dict.swift +14 -1
  13. package/ios/Extensions/TCFUserDecisions+Dict.swift +12 -1
  14. package/ios/Extensions/UsercentricsCMPData+Dict.swift +96 -7
  15. package/ios/Manager/UsercentricsManager.swift +6 -1
  16. package/ios/RNUsercentricsModule.m +3 -0
  17. package/ios/RNUsercentricsModule.swift +7 -3
  18. package/lib/Usercentrics.d.ts +5 -3
  19. package/lib/Usercentrics.js +4 -0
  20. package/lib/Usercentrics.js.map +1 -1
  21. package/lib/models/AdditionalConsentModeData.d.ts +12 -0
  22. package/lib/models/AdditionalConsentModeData.js +15 -0
  23. package/lib/models/AdditionalConsentModeData.js.map +1 -0
  24. package/lib/models/BannerSettings.js.map +1 -1
  25. package/lib/models/CCPAData.js.map +1 -1
  26. package/lib/models/CCPASettings.js.map +1 -1
  27. package/lib/models/ConsentDisclosureObject.d.ts +20 -0
  28. package/lib/models/ConsentDisclosureObject.js +24 -0
  29. package/lib/models/ConsentDisclosureObject.js.map +1 -0
  30. package/lib/models/FirstLayerSettings.js.map +1 -1
  31. package/lib/models/NetworkMode.js.map +1 -1
  32. package/lib/models/SecondLayerSettings.js.map +1 -1
  33. package/lib/models/TCF2Settings.d.ts +24 -1
  34. package/lib/models/TCF2Settings.js +27 -1
  35. package/lib/models/TCF2Settings.js.map +1 -1
  36. package/lib/models/TCFData.d.ts +16 -2
  37. package/lib/models/TCFData.js +17 -2
  38. package/lib/models/TCFData.js.map +1 -1
  39. package/lib/models/TCFDecisionUILayer.js.map +1 -1
  40. package/lib/models/TCFUserDecisions.d.ts +10 -4
  41. package/lib/models/TCFUserDecisions.js +8 -1
  42. package/lib/models/TCFUserDecisions.js.map +1 -1
  43. package/lib/models/UsercentricsAnalyticsEventType.js.map +1 -1
  44. package/lib/models/UsercentricsCMPData.js.map +1 -1
  45. package/lib/models/UsercentricsCategory.js.map +1 -1
  46. package/lib/models/UsercentricsConsentType.js.map +1 -1
  47. package/lib/models/UsercentricsConsentUserResponse.js.map +1 -1
  48. package/lib/models/UsercentricsLabels.d.ts +8 -1
  49. package/lib/models/UsercentricsLabels.js +8 -1
  50. package/lib/models/UsercentricsLabels.js.map +1 -1
  51. package/lib/models/UsercentricsLoggerLevel.js.map +1 -1
  52. package/lib/models/UsercentricsOptions.js.map +1 -1
  53. package/lib/models/UsercentricsReadyStatus.js.map +1 -1
  54. package/lib/models/UsercentricsService.d.ts +4 -1
  55. package/lib/models/UsercentricsService.js +3 -1
  56. package/lib/models/UsercentricsService.js.map +1 -1
  57. package/lib/models/UsercentricsServiceConsent.js.map +1 -1
  58. package/lib/models/UsercentricsSettings.d.ts +33 -4
  59. package/lib/models/UsercentricsSettings.js +38 -3
  60. package/lib/models/UsercentricsSettings.js.map +1 -1
  61. package/lib/models/UsercentricsUserInteraction.js.map +1 -1
  62. package/lib/models/UsercentricsVariant.js.map +1 -1
  63. package/package.json +2 -2
@@ -8,6 +8,8 @@ import com.usercentrics.sdk.services.tcf.interfaces.TCFSpecialFeature
8
8
  import com.usercentrics.sdk.services.tcf.interfaces.TCFSpecialPurpose
9
9
  import com.usercentrics.sdk.services.tcf.interfaces.TCFStack
10
10
  import com.usercentrics.sdk.services.tcf.interfaces.TCFVendor
11
+ import com.usercentrics.sdk.services.tcf.interfaces.TCFVendorRestriction
12
+ import com.usercentrics.tcf.core.model.RestrictionType
11
13
  import com.usercentrics.tcf.core.model.gvl.VendorUrl
12
14
 
13
15
  internal class GetTCFDataMock {
@@ -33,6 +35,7 @@ internal class GetTCFDataMock {
33
35
  showConsentToggle = false,
34
36
  showLegitimateInterestToggle = false,
35
37
  stackId = null,
38
+ numberOfVendors = 1,
36
39
  )
37
40
  ),
38
41
  specialFeatures = listOf(
@@ -89,7 +92,6 @@ internal class GetTCFDataMock {
89
92
  IdAndName(7, ""),
90
93
  IdAndName(8, "")
91
94
  ),
92
- restrictions = listOf(),
93
95
  specialFeatures = listOf(IdAndName(1, "")),
94
96
  specialPurposes = listOf(),
95
97
  showConsentToggle = true,
@@ -103,14 +105,16 @@ internal class GetTCFDataMock {
103
105
  dataSharedOutsideEU = false,
104
106
  dataRetention = null,
105
107
  dataCategories = listOf(IdAndName(id = 123, name = "name")),
106
- vendorUrls = listOf(VendorUrl(langId = "langId", privacy = "privacy", legIntClaim = "legIntClaim"))
108
+ vendorUrls = listOf(VendorUrl(langId = "langId", privacy = "privacy", legIntClaim = "legIntClaim")),
109
+ restrictions = listOf(
110
+ TCFVendorRestriction(purposeId = 1, restrictionType = RestrictionType.REQUIRE_LI)
111
+ ),
107
112
  )
108
113
  ),
109
114
  tcString = "abc",
110
115
  thirdPartyCount = 123,
111
116
  )
112
117
 
113
- // From the debugger
114
118
  val expected = mapOf(
115
119
  "features" to listOf(
116
120
  mapOf(
@@ -132,6 +136,7 @@ internal class GetTCFDataMock {
132
136
  "showConsentToggle" to false,
133
137
  "showLegitimateInterestToggle" to false,
134
138
  "stackId" to null,
139
+ "numberOfVendors" to 1
135
140
  )
136
141
  ),
137
142
  "specialFeatures" to listOf(
@@ -159,7 +164,6 @@ internal class GetTCFDataMock {
159
164
  "description" to "Ads can be personalised based on a profile. More data can be added to better personalise ads.",
160
165
  "id" to 3,
161
166
  "name" to "Personalised ads",
162
-
163
167
  "purposeIds" to listOf(
164
168
  2,
165
169
  3,
@@ -200,6 +204,12 @@ internal class GetTCFDataMock {
200
204
  "dataRetention" to null,
201
205
  "dataCategories" to listOf(123),
202
206
  "vendorUrls" to listOf(mapOf("langId" to "langId", "privacy" to "privacy", "legIntClaim" to "legIntClaim")),
207
+ "restrictions" to listOf(
208
+ mapOf(
209
+ "purposeId" to 1,
210
+ "restrictionType" to 2
211
+ )
212
+ )
203
213
  ),
204
214
  ),
205
215
  "tcString" to "abc",
@@ -54,6 +54,12 @@ internal class SaveDecisionsForTCFMock {
54
54
  "legitimateInterestConsent" to null
55
55
  )
56
56
  ),
57
+ "adTechProviders" to listOf(
58
+ mapOf(
59
+ "id" to 43,
60
+ "consent" to true,
61
+ )
62
+ )
57
63
  ),
58
64
  "fromLayer" to "FIRST_LAYER",
59
65
  "serviceDecisions" to listOf(
@@ -82,4 +88,4 @@ internal class SaveDecisionsForTCFMock {
82
88
  )
83
89
  )
84
90
  }
85
- }
91
+ }
@@ -89,6 +89,11 @@ internal class RNUsercentricsModule(
89
89
  promise.resolve(usercentricsProxy.instance.getCMPData().serialize())
90
90
  }
91
91
 
92
+ @ReactMethod
93
+ fun getAdditionalConsentModeData(promise: Promise) {
94
+ promise.resolve(usercentricsProxy.instance.getAdditionalConsentModeData().serialize())
95
+ }
96
+
92
97
  @ReactMethod
93
98
  fun setCMPId(id: Int) {
94
99
  usercentricsProxy.instance.setCMPId(id)
@@ -163,7 +168,11 @@ internal class RNUsercentricsModule(
163
168
 
164
169
  @ReactMethod
165
170
  fun saveDecisionsForTCF(
166
- tcfDecisions: ReadableMap, fromLayer: Int, saveDecisions: ReadableArray, consentType: Int, promise: Promise
171
+ tcfDecisions: ReadableMap,
172
+ fromLayer: Int,
173
+ saveDecisions: ReadableArray,
174
+ consentType: Int,
175
+ promise: Promise
167
176
  ) {
168
177
  promise.resolve(
169
178
  usercentricsProxy.instance.saveDecisionsForTCF(
@@ -0,0 +1,24 @@
1
+ package com.usercentrics.reactnativeusercentrics.extensions
2
+
3
+ import com.usercentrics.sdk.v2.settings.data.ConsentDisclosure
4
+ import com.usercentrics.sdk.v2.settings.data.ConsentDisclosureObject
5
+
6
+ internal fun ConsentDisclosureObject?.serialize(): Any? {
7
+ if (this == null) {
8
+ return null
9
+ }
10
+ return disclosures.map { it.serialize() }
11
+ }
12
+
13
+ internal fun ConsentDisclosure.serialize(): Any {
14
+ return mapOf(
15
+ "identifier" to identifier,
16
+ "type" to type?.ordinal,
17
+ "name" to name,
18
+ "maxAgeSeconds" to maxAgeSeconds,
19
+ "cookieRefresh" to cookieRefresh,
20
+ "purposes" to purposes,
21
+ "domain" to domain,
22
+ "description" to description,
23
+ )
24
+ }
@@ -8,7 +8,7 @@ import com.usercentrics.sdk.services.tcf.interfaces.TCFSpecialFeature
8
8
  import com.usercentrics.sdk.services.tcf.interfaces.TCFSpecialPurpose
9
9
  import com.usercentrics.sdk.services.tcf.interfaces.TCFStack
10
10
  import com.usercentrics.sdk.services.tcf.interfaces.TCFVendor
11
- import com.usercentrics.tcf.core.model.gvl.DataRetention
11
+ import com.usercentrics.sdk.services.tcf.interfaces.TCFVendorRestriction
12
12
  import com.usercentrics.tcf.core.model.gvl.VendorUrl
13
13
 
14
14
  internal fun TCFData.serialize(): WritableMap {
@@ -45,6 +45,7 @@ private fun TCFPurpose.serialize(): WritableMap {
45
45
  "showConsentToggle" to showConsentToggle,
46
46
  "showLegitimateInterestToggle" to showLegitimateInterestToggle,
47
47
  "stackId" to stackId,
48
+ "numberOfVendors" to numberOfVendors,
48
49
  ).toWritableMap()
49
50
  }
50
51
 
@@ -92,7 +93,6 @@ private fun TCFVendor.serialize(): WritableMap {
92
93
  "name" to name,
93
94
  "policyUrl" to policyUrl,
94
95
  "purposes" to purposes.map { it.id },
95
- // "restrictions" to restrictions.map { restrictions.serialize() },
96
96
  "specialFeatures" to specialFeatures.map { it.id },
97
97
  "specialPurposes" to specialPurposes.map { it.id },
98
98
  "showConsentToggle" to showConsentToggle,
@@ -100,12 +100,13 @@ private fun TCFVendor.serialize(): WritableMap {
100
100
  "cookieMaxAgeSeconds" to cookieMaxAgeSeconds,
101
101
  "usesNonCookieAccess" to usesNonCookieAccess,
102
102
  "deviceStorageDisclosureUrl" to deviceStorageDisclosureUrl,
103
- // "deviceStorage" to deviceStorage.serialize(),
104
103
  "usesCookies" to usesCookies,
105
104
  "cookieRefresh" to cookieRefresh,
106
105
  "dataSharedOutsideEU" to dataSharedOutsideEU,
107
106
  "dataCategories" to dataCategories.map { it.id },
108
- "vendorUrls" to vendorUrls.map { it.serialize() }
107
+ "vendorUrls" to vendorUrls.map { it.serialize() },
108
+ "deviceStorage" to deviceStorage.serialize(),
109
+ "restrictions" to restrictions.map { it.serialize() }
109
110
  ).toWritableMap()
110
111
  }
111
112
 
@@ -116,3 +117,10 @@ private fun VendorUrl.serialize(): WritableMap {
116
117
  "legIntClaim" to legIntClaim
117
118
  ).toWritableMap()
118
119
  }
120
+
121
+ private fun TCFVendorRestriction.serialize(): WritableMap {
122
+ return mapOf(
123
+ "purposeId" to purposeId,
124
+ "restrictionType" to restrictionType.ordinal
125
+ ).toWritableMap()
126
+ }
@@ -3,6 +3,7 @@ package com.usercentrics.reactnativeusercentrics.extensions
3
3
  import com.facebook.react.bridge.ReadableArray
4
4
  import com.facebook.react.bridge.ReadableMap
5
5
  import com.usercentrics.sdk.UserDecision
6
+ import com.usercentrics.sdk.services.tcf.interfaces.AdTechProviderDecision
6
7
  import com.usercentrics.sdk.services.tcf.interfaces.TCFUserDecisionOnPurpose
7
8
  import com.usercentrics.sdk.services.tcf.interfaces.TCFUserDecisionOnSpecialFeature
8
9
  import com.usercentrics.sdk.services.tcf.interfaces.TCFUserDecisionOnVendor
@@ -47,10 +48,19 @@ internal fun ReadableMap.deserializeTCFUserDecisions(): TCFUserDecisions {
47
48
  list
48
49
  }
49
50
 
51
+ val adTechProviderDecisions = getArray("adTechProviders")?.let {
52
+ val list = mutableListOf<AdTechProviderDecision>()
53
+ for (i in 0 until it.size()) {
54
+ list.add(it.getMap(i).deserializeAdTechProviderDecision())
55
+ }
56
+ list
57
+ }
58
+
50
59
  return TCFUserDecisions(
51
60
  purposes = purposes,
52
61
  specialFeatures = specialFeature,
53
62
  vendors = vendors,
63
+ adTechProviders = adTechProviderDecisions ?: emptyList(),
54
64
  )
55
65
  }
56
66
 
@@ -75,4 +85,11 @@ private fun ReadableMap.deserializeTCFUserDecisionOnVendor(): TCFUserDecisionOnV
75
85
  consent = getBooleanOrNull("consent"),
76
86
  legitimateInterestConsent = getBooleanOrNull("legitimateInterestConsent"),
77
87
  )
78
- }
88
+ }
89
+
90
+ private fun ReadableMap.deserializeAdTechProviderDecision(): AdTechProviderDecision {
91
+ return AdTechProviderDecision(
92
+ id = getInt("id"),
93
+ consent = getBooleanOrNull("consent") ?: false,
94
+ )
95
+ }
@@ -2,9 +2,24 @@ package com.usercentrics.reactnativeusercentrics.extensions
2
2
 
3
3
  import com.facebook.react.bridge.Arguments
4
4
  import com.facebook.react.bridge.WritableMap
5
+ import com.usercentrics.sdk.AdTechProvider
6
+ import com.usercentrics.sdk.AdditionalConsentModeData
5
7
  import com.usercentrics.sdk.UsercentricsCMPData
6
8
  import com.usercentrics.sdk.v2.location.data.UsercentricsLocation
7
- import com.usercentrics.sdk.v2.settings.data.*
9
+ import com.usercentrics.sdk.v2.settings.data.CCPASettings
10
+ import com.usercentrics.sdk.v2.settings.data.CustomizationColor
11
+ import com.usercentrics.sdk.v2.settings.data.CustomizationFont
12
+ import com.usercentrics.sdk.v2.settings.data.FirstLayer
13
+ import com.usercentrics.sdk.v2.settings.data.PublishedApp
14
+ import com.usercentrics.sdk.v2.settings.data.SecondLayer
15
+ import com.usercentrics.sdk.v2.settings.data.TCF2ChangedPurposes
16
+ import com.usercentrics.sdk.v2.settings.data.TCF2Settings
17
+ import com.usercentrics.sdk.v2.settings.data.UsercentricsCategory
18
+ import com.usercentrics.sdk.v2.settings.data.UsercentricsCustomization
19
+ import com.usercentrics.sdk.v2.settings.data.UsercentricsLabels
20
+ import com.usercentrics.sdk.v2.settings.data.UsercentricsService
21
+ import com.usercentrics.sdk.v2.settings.data.UsercentricsSettings
22
+ import com.usercentrics.sdk.v2.settings.data.VariantsSettings
8
23
 
9
24
  internal fun UsercentricsCMPData.serialize(): WritableMap {
10
25
  return Arguments.createMap().apply {
@@ -40,12 +55,15 @@ private fun UsercentricsSettings.serialize(): WritableMap {
40
55
  "enablePoweredBy" to enablePoweredBy,
41
56
  "editableLanguages" to editableLanguages,
42
57
  "customization" to customization?.serialize(),
58
+ "variants" to variants?.serialize(),
59
+ "dpsDisplayFormat" to dpsDisplayFormat?.ordinal,
60
+ "framework" to framework?.ordinal,
61
+ "publishedApps" to publishedApps?.map { it.serialize() },
43
62
  ).toWritableMap()
44
63
  }
45
64
 
46
65
  private fun UsercentricsLabels.serialize(): Map<String, Any?> {
47
66
  return mapOf(
48
- // Required only
49
67
  "btnAcceptAll" to btnAcceptAll,
50
68
  "btnDeny" to btnDeny,
51
69
  "btnSave" to btnSave,
@@ -111,7 +129,14 @@ private fun UsercentricsLabels.serialize(): Map<String, Any?> {
111
129
  "secondLayerTitle" to secondLayerTitle,
112
130
  "secondLayerDescriptionHtml" to secondLayerDescriptionHtml,
113
131
  "btnMore" to btnMore,
114
- "explicit" to (explicit ?: "")
132
+ "explicit" to (explicit ?: ""),
133
+ "transferToThirdCountriesInfo" to transferToThirdCountriesInfo,
134
+ "more" to more,
135
+ "headerModal" to headerModal,
136
+ "furtherInformationOptOut" to furtherInformationOptOut,
137
+ "cookiePolicyLinkText" to cookiePolicyLinkText,
138
+ "noImplicit" to noImplicit,
139
+ "yesImplicit" to yesImplicit,
115
140
  )
116
141
  }
117
142
 
@@ -136,7 +161,6 @@ private fun CCPASettings.serialize(): WritableMap {
136
161
 
137
162
  private fun TCF2Settings.serialize(): WritableMap {
138
163
  return mapOf(
139
- // Required
140
164
  "firstLayerTitle" to firstLayerTitle,
141
165
  "secondLayerTitle" to secondLayerTitle,
142
166
  "tabsPurposeLabel" to tabsPurposeLabel,
@@ -160,7 +184,6 @@ private fun TCF2Settings.serialize(): WritableMap {
160
184
  "linksVendorListLinkLabel" to linksVendorListLinkLabel,
161
185
  "cmpId" to cmpId,
162
186
  "cmpVersion" to cmpVersion,
163
- // Optional
164
187
  "firstLayerHideToggles" to firstLayerHideToggles,
165
188
  "secondLayerHideToggles" to secondLayerHideToggles,
166
189
  "hideLegitimateInterestToggles" to hideLegitimateInterestToggles,
@@ -189,6 +212,14 @@ private fun TCF2Settings.serialize(): WritableMap {
189
212
  "legitimateInterestLabel" to legitimateInterestLabel,
190
213
  "version" to version,
191
214
  "examplesLabel" to examplesLabel,
215
+ "firstLayerMobileVariant" to firstLayerMobileVariant?.ordinal,
216
+ "showDataSharedOutsideEUText" to showDataSharedOutsideEUText,
217
+ "dataSharedOutsideEUText" to dataSharedOutsideEUText,
218
+ "vendorIdsOutsideEUList" to vendorIdsOutsideEUList,
219
+ "scope" to scope.ordinal,
220
+ "changedPurposes" to changedPurposes?.serialize(),
221
+ "acmV2Enabled" to acmV2Enabled,
222
+ "selectedATPIds" to selectedATPIds,
192
223
  ).toWritableMap()
193
224
  }
194
225
 
@@ -250,6 +281,8 @@ private fun SecondLayer.serialize(): WritableMap {
250
281
  "denyButtonText" to (denyButtonText ?: ""),
251
282
  "hideButtonDeny" to hideButtonDeny,
252
283
  "hideLanguageSwitch" to hideLanguageSwitch,
284
+ "hideTogglesForServices" to hideTogglesForServices,
285
+ "hideDataProcessingServices" to hideDataProcessingServices,
253
286
  ).toWritableMap()
254
287
  }
255
288
 
@@ -291,11 +324,12 @@ private fun UsercentricsService.serialize(): WritableMap {
291
324
  "deviceStorageDisclosureUrl" to deviceStorageDisclosureUrl,
292
325
  "isDeactivated" to isDeactivated,
293
326
  "disableLegalBasis" to disableLegalBasis,
294
- "technologyUsed" to technologyUsed
327
+ "technologyUsed" to technologyUsed,
328
+ "deviceStorage" to deviceStorage.serialize(),
329
+ "isHidden" to isHidden,
295
330
  ).toWritableMap()
296
331
  }
297
332
 
298
-
299
333
  private fun UsercentricsCategory.serialize(): WritableMap {
300
334
  return mapOf(
301
335
  "categorySlug" to categorySlug,
@@ -314,3 +348,47 @@ private fun UsercentricsLocation.serialize(): WritableMap {
314
348
  "isInCalifornia" to isInCalifornia(),
315
349
  ).toWritableMap()
316
350
  }
351
+
352
+ private fun VariantsSettings?.serialize(): Any? {
353
+ if (this == null) {
354
+ return null
355
+ }
356
+ return mapOf(
357
+ "enabled" to enabled,
358
+ "experimentsJson" to experimentsJson,
359
+ "activateWith" to activateWith,
360
+ )
361
+ }
362
+
363
+ private fun PublishedApp.serialize(): Any {
364
+ return mapOf(
365
+ "bundleId" to bundleId,
366
+ "platform" to platform.ordinal,
367
+ )
368
+ }
369
+
370
+ private fun TCF2ChangedPurposes?.serialize(): Any? {
371
+ if (this == null) {
372
+ return null
373
+ }
374
+ return mapOf(
375
+ "purposes" to purposes,
376
+ "legIntPurposes" to legIntPurposes
377
+ )
378
+ }
379
+
380
+ internal fun AdditionalConsentModeData.serialize(): WritableMap {
381
+ return Arguments.createMap().apply {
382
+ putString("acString", acString)
383
+ putArray("adTechProviders", adTechProviders.map { it.serialize() }.serialize())
384
+ }
385
+ }
386
+
387
+ private fun AdTechProvider.serialize(): WritableMap {
388
+ return mapOf(
389
+ "consent" to consent,
390
+ "id" to id,
391
+ "name" to name,
392
+ "privacyPolicyUrl" to privacyPolicyUrl,
393
+ ).toWritableMap()
394
+ }
@@ -40,6 +40,7 @@ extension TCFPurpose {
40
40
  "showConsentToggle" : showConsentToggle,
41
41
  "showLegitimateInterestToggle" : showLegitimateInterestToggle,
42
42
  "stackId" : stackId as Any,
43
+ "numberOfVendors": numberOfVendors as Any
43
44
  ]
44
45
  }
45
46
  }
@@ -107,7 +108,9 @@ extension TCFVendor {
107
108
  "cookieRefresh" : cookieRefresh?.boolValue as Any,
108
109
  "dataSharedOutsideEU": dataSharedOutsideEU?.boolValue as Any,
109
110
  "dataCategories": dataCategories.map { $0.id },
110
- "vendorUrls": vendorUrls.map { $0.toDictionary() }
111
+ "vendorUrls": vendorUrls.map { $0.toDictionary() },
112
+ "deviceStorage" : self.deviceStorage?.toDictionary() as Any,
113
+ "restrictions" : self.restrictions.map { $0.toDictionary() }
111
114
  ]
112
115
  }
113
116
  }
@@ -122,3 +125,13 @@ extension VendorUrl {
122
125
  ]
123
126
  }
124
127
  }
128
+
129
+ extension TCFVendorRestriction {
130
+
131
+ func toDictionary() -> NSDictionary {
132
+ return [
133
+ "purposeId" : self.purposeId,
134
+ "restrictionType" : self.restrictionType.ordinal
135
+ ]
136
+ }
137
+ }
@@ -6,10 +6,12 @@ public extension TCFUserDecisions {
6
6
  let purposes = dict["purposes"] as? [NSDictionary]
7
7
  let specialFeatures = dict["specialFeatures"] as? [NSDictionary]
8
8
  let vendors = dict["vendors"] as? [NSDictionary]
9
+ let adTechProviders = dict["adTechProviders"] as? [NSDictionary]
9
10
 
10
11
  self.init(purposes: purposes?.compactMap { TCFUserDecisionOnPurpose(from: $0) },
11
12
  specialFeatures: specialFeatures?.compactMap { TCFUserDecisionOnSpecialFeature(from: $0) },
12
- vendors: vendors?.compactMap { TCFUserDecisionOnVendor(from: $0) })
13
+ vendors: vendors?.compactMap { TCFUserDecisionOnVendor(from: $0) },
14
+ adTechProviders: adTechProviders?.compactMap { AdTechProviderDecision(from: $0) } ?? [])
13
15
  }
14
16
  }
15
17
 
@@ -66,3 +68,12 @@ extension TCFUserDecisionOnVendor {
66
68
  legitimateInterestConsent: legitimateInterestConsent)
67
69
  }
68
70
  }
71
+
72
+ extension AdTechProviderDecision {
73
+ convenience init?(from dict: NSDictionary) {
74
+ guard let id = dict["id"] as? Int else { return nil }
75
+
76
+ var consent = dict["consent"] as? Bool
77
+ self.init(id: Int32(id), consent: consent ?? false)
78
+ }
79
+ }
@@ -39,6 +39,10 @@ extension UsercentricsSettings {
39
39
  "enablePoweredBy" : self.enablePoweredBy,
40
40
  "editableLanguages" : self.editableLanguages,
41
41
  "customization" : self.customization?.toDictionary() as Any,
42
+ "variants": (self.variants?.toDictionary() ?? nil) as Any,
43
+ "dpsDisplayFormat": (self.dpsDisplayFormat?.ordinal ?? nil) as Any,
44
+ "framework": (self.framework?.ordinal ?? nil) as Any,
45
+ "publishedApps": (self.publishedApps?.map { $0.toDictionary() } ?? nil) as Any,
42
46
  ]
43
47
  }
44
48
  }
@@ -46,7 +50,6 @@ extension UsercentricsSettings {
46
50
  extension UsercentricsLabels {
47
51
  func toDictionary() -> NSDictionary {
48
52
  return [
49
- // Required only
50
53
  "btnAcceptAll" : self.btnAcceptAll,
51
54
  "btnDeny" : self.btnDeny,
52
55
  "btnSave" : self.btnSave,
@@ -112,7 +115,14 @@ extension UsercentricsLabels {
112
115
  "secondLayerDescriptionHtml" : self.secondLayerDescriptionHtml,
113
116
  "secondLayerTitle" : self.secondLayerTitle ?? "",
114
117
  "btnMore": self.btnMore,
115
- "explicit": self.explicit_ ?? ""
118
+ "explicit": self.explicit_ ?? "",
119
+ "transferToThirdCountriesInfo": self.transferToThirdCountriesInfo,
120
+ "more": self.more,
121
+ "headerModal": self.headerModal,
122
+ "furtherInformationOptOut": self.furtherInformationOptOut,
123
+ "cookiePolicyLinkText": self.cookiePolicyLinkText,
124
+ "noImplicit": self.noImplicit,
125
+ "yesImplicit": self.yesImplicit,
116
126
  ]
117
127
  }
118
128
  }
@@ -142,7 +152,6 @@ extension CCPASettings {
142
152
  extension TCF2Settings {
143
153
  func toDictionary() -> NSDictionary {
144
154
  return [
145
- // Required
146
155
  "firstLayerTitle" : self.firstLayerTitle,
147
156
  "secondLayerTitle" : self.secondLayerTitle,
148
157
  "tabsPurposeLabel" : self.tabsPurposeLabel,
@@ -166,7 +175,6 @@ extension TCF2Settings {
166
175
  "linksVendorListLinkLabel" : self.linksVendorListLinkLabel,
167
176
  "cmpId" : self.cmpId,
168
177
  "cmpVersion" : self.cmpVersion,
169
- // Optional
170
178
  "firstLayerHideToggles" : self.firstLayerHideToggles,
171
179
  "secondLayerHideToggles" : self.secondLayerHideToggles,
172
180
  "hideLegitimateInterestToggles" : self.hideLegitimateInterestToggles,
@@ -196,6 +204,14 @@ extension TCF2Settings {
196
204
  "legitimateInterestLabel": self.legitimateInterestLabel,
197
205
  "version": self.version,
198
206
  "examplesLabel": self.examplesLabel,
207
+ "firstLayerMobileVariant": (self.firstLayerMobileVariant?.ordinal ?? nil) as Any,
208
+ "showDataSharedOutsideEUText": self.showDataSharedOutsideEUText,
209
+ "dataSharedOutsideEUText": self.dataSharedOutsideEUText as Any,
210
+ "vendorIdsOutsideEUList": self.vendorIdsOutsideEUList,
211
+ "scope": self.scope.ordinal,
212
+ "changedPurposes": self.changedPurposes?.toDictionary() as Any,
213
+ "acmV2Enabled": self.acmV2Enabled,
214
+ "selectedATPIds": self.selectedATPIds
199
215
  ]
200
216
  }
201
217
  }
@@ -266,23 +282,22 @@ extension FirstLayer {
266
282
  }
267
283
 
268
284
 
269
-
270
285
  extension SecondLayer {
271
286
  func toDictionary() -> NSDictionary {
272
287
  return [
273
- // Required
274
288
  "tabsCategoriesLabel" : self.tabsCategoriesLabel,
275
289
  "tabsServicesLabel" : self.tabsServicesLabel,
276
290
  "hideButtonDeny" : hideButtonDeny?.boolValue as Any,
277
291
  "hideLanguageSwitch" : hideLanguageSwitch?.boolValue as Any,
278
292
  "acceptButtonText": self.acceptButtonText ?? "",
279
293
  "denyButtonText": self.denyButtonText ?? "",
294
+ "hideTogglesForServices": self.hideTogglesForServices,
295
+ "hideDataProcessingServices": self.hideDataProcessingServices,
280
296
  ]
281
297
  }
282
298
  }
283
299
 
284
300
 
285
-
286
301
  extension UsercentricsService {
287
302
  func toDictionary() -> NSDictionary {
288
303
  return [
@@ -323,10 +338,34 @@ extension UsercentricsService {
323
338
  "isDeactivated" : isDeactivated?.boolValue as Any,
324
339
  "disableLegalBasis" : disableLegalBasis?.boolValue as Any,
325
340
  "technologyUsed": self.technologyUsed,
341
+ "deviceStorage": self.deviceStorage.toDictionary(),
342
+ "isHidden": self.isHidden
343
+ ]
344
+ }
345
+ }
346
+
347
+ extension ConsentDisclosureObject {
348
+ func toDictionary() -> Any {
349
+ return self.disclosures.map { $0.toDictionary() }
350
+ }
351
+ }
352
+
353
+ extension ConsentDisclosure {
354
+ func toDictionary() -> Any {
355
+ return [
356
+ "identifier": self.identifier as Any,
357
+ "type": self.type?.ordinal ?? "",
358
+ "name": self.name as Any,
359
+ "maxAgeSeconds": self.maxAgeSeconds as Any,
360
+ "cookieRefresh": self.cookieRefresh,
361
+ "purposes": self.purposes,
362
+ "domain": self.domain ?? "",
363
+ "description": self.description,
326
364
  ]
327
365
  }
328
366
  }
329
367
 
368
+
330
369
  extension UsercentricsCategory {
331
370
  func toDictionary() -> Any? {
332
371
  return [
@@ -395,3 +434,53 @@ extension TranslationAriaLabels {
395
434
  ]
396
435
  }
397
436
  }
437
+
438
+ extension VariantsSettings {
439
+ func toDictionary() -> Any {
440
+ return [
441
+ "enabled": enabled,
442
+ "experimentsJson": experimentsJson,
443
+ "activateWith": activateWith,
444
+ ] as [String : Any]
445
+ }
446
+ }
447
+
448
+ extension PublishedApp {
449
+ func toDictionary() -> Any {
450
+ return [
451
+ "bundleId": bundleId,
452
+ "platform": platform.ordinal,
453
+ ]
454
+ }
455
+ }
456
+
457
+ extension TCF2ChangedPurposes {
458
+ func toDictionary() -> Any {
459
+ return [
460
+ "purposes": purposes,
461
+ "legIntPurposes": legIntPurposes
462
+ ]
463
+ }
464
+ }
465
+
466
+ extension AdditionalConsentModeData {
467
+
468
+ func toDictionary() -> NSDictionary {
469
+ return [
470
+ "acString": self.acString,
471
+ "adTechProviders": self.adTechProviders.map { $0.toDictionary() }
472
+ ]
473
+ }
474
+ }
475
+
476
+ extension AdTechProvider {
477
+
478
+ func toDictionary() -> NSDictionary {
479
+ return [
480
+ "id" : id,
481
+ "name" : name,
482
+ "privacyPolicyUrl" : privacyPolicyUrl,
483
+ "consent" : consent
484
+ ]
485
+ }
486
+ }
@@ -21,6 +21,7 @@ public protocol UsercentricsManager {
21
21
  func getUSPData() -> CCPAData
22
22
  func getTCFData(callback: @escaping (TCFData) -> Void)
23
23
  func getABTestingVariant() -> String?
24
+ func getAdditionalConsentModeData() -> AdditionalConsentModeData
24
25
 
25
26
  func changeLanguage(language: String, onSuccess: @escaping (() -> Void), onFailure: @escaping ((Error) -> Void))
26
27
 
@@ -98,7 +99,11 @@ final class UsercentricsManagerImplementation: UsercentricsManager {
98
99
  func getTCFData(callback: @escaping (TCFData) -> Void) {
99
100
  UsercentricsCore.shared.getTCFData(callback: callback)
100
101
  }
101
-
102
+
103
+ func getAdditionalConsentModeData() -> AdditionalConsentModeData {
104
+ return UsercentricsCore.shared.getAdditionalConsentModeData()
105
+ }
106
+
102
107
  func changeLanguage(language: String, onSuccess: @escaping (() -> Void), onFailure: @escaping ((Error) -> Void)) {
103
108
  UsercentricsCore.shared.changeLanguage(language: language, onSuccess: onSuccess, onFailure: onFailure)
104
109
  }
@@ -53,6 +53,9 @@ RCT_EXTERN_METHOD(getUSPData:(RCTPromiseResolveBlock)resolve
53
53
  RCT_EXTERN_METHOD(getTCFData:(RCTPromiseResolveBlock)resolve
54
54
  reject:(RCTPromiseRejectBlock)reject)
55
55
 
56
+ RCT_EXTERN_METHOD(getAdditionalConsentModeData:(RCTPromiseResolveBlock)resolve
57
+ reject:(RCTPromiseRejectBlock)reject)
58
+
56
59
  RCT_EXTERN_METHOD(changeLanguage:(NSString *)language
57
60
  resolve:(RCTPromiseResolveBlock)resolve
58
61
  reject:(RCTPromiseRejectBlock)reject)
@@ -113,9 +113,13 @@ class RNUsercentricsModule: NSObject, RCTBridgeModule {
113
113
  }
114
114
 
115
115
  @objc func getABTestingVariant(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
116
- resolve(usercentricsManager.getABTestingVariant())
117
- }
118
-
116
+ resolve(usercentricsManager.getABTestingVariant())
117
+ }
118
+
119
+ @objc func getAdditionalConsentModeData(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
120
+ resolve(usercentricsManager.getAdditionalConsentModeData().toDictionary())
121
+ }
122
+
119
123
  @objc func changeLanguage(_ language: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
120
124
  usercentricsManager.changeLanguage(language: language) {
121
125
  resolve(Void.self)