@usercentrics/react-native-sdk 2.3.0 → 2.5.2

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 (45) hide show
  1. package/CHANGELOG.md +45 -1
  2. package/android/build.gradle +1 -1
  3. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/RNUsercentricsModuleTest.kt +9 -19
  4. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/api/FakeUsercentricsProxy.kt +4 -11
  5. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetTCFDataMock.kt +3 -1
  6. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetUSPDataMock.kt +1 -0
  7. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/RNUsercentricsModule.kt +8 -38
  8. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/api/UsercentricsProxy.kt +12 -42
  9. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/CCPADataExtensions.kt +1 -0
  10. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/FirstLayerOptionsExtensions.kt +26 -2
  11. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/TCFDataExtensions.kt +2 -1
  12. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/UserOptionsExtensions.kt +12 -0
  13. package/ios/Extensions/BannerSettings+Dict.swift +42 -2
  14. package/ios/Extensions/CCPAData+Dict.swift +1 -0
  15. package/ios/Extensions/UsercentricsOptions+Dict.swift +20 -6
  16. package/ios/Manager/UsercentricsManager.swift +4 -25
  17. package/ios/RNUsercentricsModule.swift +36 -28
  18. package/lib/Usercentrics.d.ts +4 -1
  19. package/lib/Usercentrics.js +4 -1
  20. package/lib/Usercentrics.js.map +1 -1
  21. package/lib/models/BannerSettings.d.ts +11 -1
  22. package/lib/models/BannerSettings.js +11 -1
  23. package/lib/models/BannerSettings.js.map +1 -1
  24. package/lib/models/CCPAData.d.ts +2 -1
  25. package/lib/models/CCPAData.js +2 -1
  26. package/lib/models/CCPAData.js.map +1 -1
  27. package/lib/models/FirstLayerOptions.d.ts +1 -2
  28. package/lib/models/FirstLayerOptions.js +1 -2
  29. package/lib/models/FirstLayerOptions.js.map +1 -1
  30. package/lib/models/NetworkMode.d.ts +4 -0
  31. package/lib/models/NetworkMode.js +6 -0
  32. package/lib/models/NetworkMode.js.map +1 -0
  33. package/lib/models/SecondLayerOptions.d.ts +7 -3
  34. package/lib/models/SecondLayerOptions.js +6 -1
  35. package/lib/models/SecondLayerOptions.js.map +1 -1
  36. package/lib/models/TCFData.d.ts +2 -1
  37. package/lib/models/TCFData.js +2 -1
  38. package/lib/models/TCFData.js.map +1 -1
  39. package/lib/models/UsercentricsOptions.d.ts +3 -2
  40. package/lib/models/UsercentricsOptions.js +2 -1
  41. package/lib/models/UsercentricsOptions.js.map +1 -1
  42. package/lib/models/index.d.ts +12 -11
  43. package/lib/models/index.js +12 -11
  44. package/lib/models/index.js.map +1 -1
  45. package/package.json +79 -79
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  [Release Notes](https://docs.usercentrics.com/cmp_in_app_sdk/latest/about/history/)
2
2
 
3
+ # 2.5.2
4
+
5
+ ## Resolved Issues
6
+
7
+ * TCF String solved issue when signalling legitimate interests
8
+
9
+ # 2.5.1
10
+
11
+ ## Resolved Issues
12
+
13
+ * TCF String solved issue with encoding to shorten the length of the string
14
+
15
+ # 2.5.0
16
+
17
+ ## Features
18
+
19
+ - **[UI]** Controller ID section was redesigned to have a better UX.
20
+ - `CCPAData` exposes the encoded `uspString`.
21
+
22
+ ## Improvements
23
+
24
+ - Improve stability and performance issues.
25
+
26
+ ## Resolved Issues
27
+
28
+ - General bug fixes.
29
+ - **[iOS]** Access to `rootViewController` depending on API version.
30
+
31
+ # 2.4.0
32
+
33
+ ## Features
34
+
35
+ - **[Customization]** You now have full control over the appearance of the First & Second Layer via our Admin Interface Style options and our Programmatic API. We have updated and extended our Programmatic API to simplify banner customization.
36
+ - **[UI]** Legal links are now added to our the First Layer, and can be hidden or shown as desired via programmatic API.
37
+ - **[CCPA]** Consent button can now be customized via the Admin Interface.
38
+
39
+ ## Improvements
40
+
41
+ - Improve initialization flow for stability and avoid edge case crashes.
42
+
43
+ ## Resolved Issues
44
+
45
+ - Solve stability issues and bug fixes.
46
+
3
47
  # 2.3.0
4
48
 
5
49
  ## Features
@@ -55,4 +99,4 @@
55
99
 
56
100
  # 2.0.1
57
101
 
58
- - Initial version of the library.
102
+ - Initial version of the library.
@@ -1,4 +1,4 @@
1
- def usercentrics_version = "2.3.0"
1
+ def usercentrics_version = "2.5.2"
2
2
  version usercentrics_version
3
3
 
4
4
  buildscript {
@@ -15,10 +15,12 @@ import com.usercentrics.reactnativeusercentrics.extensions.serialize
15
15
  import com.usercentrics.reactnativeusercentrics.extensions.toWritableMap
16
16
  import com.usercentrics.sdk.*
17
17
  import com.usercentrics.sdk.errors.UsercentricsError
18
+ import com.usercentrics.sdk.models.common.NetworkMode
18
19
  import com.usercentrics.sdk.models.common.UsercentricsLoggerLevel
19
20
  import com.usercentrics.sdk.models.common.UsercentricsVariant
20
21
  import com.usercentrics.sdk.models.settings.UsercentricsConsentType
21
22
  import com.usercentrics.sdk.services.tcf.TCFDecisionUILayer
23
+ import com.usercentrics.sdk.services.tcf.interfaces.TCFData
22
24
  import io.mockk.every
23
25
  import io.mockk.mockk
24
26
  import io.mockk.verify
@@ -36,6 +38,7 @@ class RNUsercentricsModuleTest {
36
38
  putInt("loggerlevel", 0)
37
39
  putInt("timeoutMillis", 1000)
38
40
  putString("version", "1.2.3")
41
+ putInt("networkMode", 1)
39
42
  }
40
43
 
41
44
  private val usercentricsConsentHistoryEntries = listOf(
@@ -94,6 +97,7 @@ class RNUsercentricsModuleTest {
94
97
  )
95
98
  assertEquals(1000L, usercentricsProxy.initializeOptionsArgument?.timeoutMillis)
96
99
  assertEquals("1.2.3", usercentricsProxy.initializeOptionsArgument?.version)
100
+ assertEquals(NetworkMode.EU, usercentricsProxy.initializeOptionsArgument?.networkMode)
97
101
  }
98
102
 
99
103
  @Test
@@ -204,21 +208,6 @@ class RNUsercentricsModuleTest {
204
208
  assertEquals("abc", promise.resolveValue)
205
209
  }
206
210
 
207
- @Test
208
- fun testGetTCString() {
209
- val usercentricsSDK = mockk<UsercentricsSDK>()
210
- every { usercentricsSDK.getTCString() }.returns("abc")
211
- val usercentricsProxy = FakeUsercentricsProxy(usercentricsSDK)
212
- val contextMock = mockk<ReactApplicationContext>(relaxed = true)
213
- val module = RNUsercentricsModule(contextMock, usercentricsProxy)
214
- val promise = FakePromise()
215
-
216
- module.getTCFString(promise)
217
-
218
- verify(exactly = 1) { usercentricsSDK.getTCString() }
219
- assertEquals("abc", promise.resolveValue)
220
- }
221
-
222
211
  @Test
223
212
  fun testGetConsents() {
224
213
  val usercentricsSDK = mockk<UsercentricsSDK>()
@@ -306,7 +295,9 @@ class RNUsercentricsModuleTest {
306
295
  @Test
307
296
  fun testGetTCFData() {
308
297
  val usercentricsSDK = mockk<UsercentricsSDK>()
309
- every { usercentricsSDK.getTCFData() }.returns(GetTCFDataMock.fake)
298
+ every { usercentricsSDK.getTCFData(any()) }.answers {
299
+ firstArg<(TCFData) -> Unit>().invoke(GetTCFDataMock.fake)
300
+ }
310
301
 
311
302
  val usercentricsProxy = FakeUsercentricsProxy(usercentricsSDK)
312
303
  val contextMock = mockk<ReactApplicationContext>(relaxed = true)
@@ -317,7 +308,7 @@ class RNUsercentricsModuleTest {
317
308
 
318
309
  val result = promise.resolveValue
319
310
 
320
- verify(exactly = 1) { usercentricsSDK.getTCFData() }
311
+ verify(exactly = 1) { usercentricsSDK.getTCFData(any()) }
321
312
  assertEquals(GetTCFDataMock.expected.toWritableMap(), result)
322
313
  }
323
314
 
@@ -563,7 +554,6 @@ class RNUsercentricsModuleTest {
563
554
  GetConsentsMock.fakeWithData
564
555
  )
565
556
 
566
-
567
557
  val usercentricsProxy = FakeUsercentricsProxy(usercentricsSDK)
568
558
  val contextMock = mockk<ReactApplicationContext>(relaxed = true)
569
559
  val module = RNUsercentricsModule(contextMock, usercentricsProxy)
@@ -590,4 +580,4 @@ class RNUsercentricsModuleTest {
590
580
 
591
581
  assertEquals(1, usercentricsProxy.resetCount)
592
582
  }
593
- }
583
+ }
@@ -53,19 +53,12 @@ internal class FakeUsercentricsProxy(
53
53
  var showFirstLayerBannerSettings: BannerSettings? = null
54
54
  var showFirstLayerStyle: FirstLayerStyleSettings? = null
55
55
 
56
- override fun showFirstLayer(
57
- activity: Activity,
58
- layout: UsercentricsLayout,
59
- bannerSettings: BannerSettings?,
60
- firstLayerStyleSettings: FirstLayerStyleSettings?,
61
- promise: Promise
62
- ) {
56
+ override fun showFirstLayer(activity: Activity, layout: UsercentricsLayout, bannerSettings: BannerSettings?, promise: Promise) {
63
57
  this.showFirstLayerLayout = layout
64
58
  this.showFirstLayerBannerSettings = bannerSettings
65
- this.showFirstLayerStyle = firstLayerStyleSettings
59
+ this.showFirstLayerStyle = bannerSettings?.firstLayerSettings
66
60
  }
67
61
 
68
- override fun showSecondLayer() {
69
-
62
+ override fun showSecondLayer(activity: Activity, bannerSettings: BannerSettings?, promise: Promise) {
70
63
  }
71
- }
64
+ }
@@ -95,6 +95,7 @@ internal class GetTCFDataMock {
95
95
  dataSharedOutsideEU = false
96
96
  )
97
97
  ),
98
+ tcString = "abc"
98
99
  )
99
100
 
100
101
  // From the debugger
@@ -186,6 +187,7 @@ internal class GetTCFDataMock {
186
187
  "dataSharedOutsideEU" to false
187
188
  ),
188
189
  ),
190
+ "tcString" to "abc"
189
191
  )
190
192
  }
191
- }
193
+ }
@@ -13,6 +13,7 @@ internal class GetUSPDataMock {
13
13
 
14
14
  // From the debugger
15
15
  val expected = mapOf(
16
+ "uspString" to "1YN-",
16
17
  "version" to 1,
17
18
  "noticeGiven" to true,
18
19
  "optedOut" to false,
@@ -3,7 +3,6 @@ package com.usercentrics.reactnativeusercentrics
3
3
  import com.facebook.react.bridge.*
4
4
  import com.usercentrics.reactnativeusercentrics.api.UsercentricsProxy
5
5
  import com.usercentrics.reactnativeusercentrics.extensions.*
6
- import com.usercentrics.sdk.UsercentricsBanner
7
6
  import com.usercentrics.sdk.models.settings.UsercentricsConsentType
8
7
  import com.usercentrics.sdk.services.tcf.TCFDecisionUILayer
9
8
 
@@ -17,17 +16,8 @@ internal class RNUsercentricsModule(
17
16
 
18
17
  @ReactMethod
19
18
  fun configure(options: ReadableMap) {
20
- var alreadyConfigured = false
21
- usercentricsProxy.isReady({
22
- alreadyConfigured = true
23
- }, {
24
- alreadyConfigured = true
25
- })
26
-
27
- if (!alreadyConfigured) {
28
- val usercentricsOptions = options.usercentricsOptionsFromMap() ?: return
29
- usercentricsProxy.initialize(reactApplicationContext, usercentricsOptions)
30
- }
19
+ val usercentricsOptions = options.usercentricsOptionsFromMap() ?: return
20
+ usercentricsProxy.initialize(reactApplicationContext, usercentricsOptions)
31
21
  }
32
22
 
33
23
  @ReactMethod
@@ -48,16 +38,7 @@ internal class RNUsercentricsModule(
48
38
  val layout = options.getString("layout")!!.usercentricsLayoutFromEnumString()
49
39
  val bannerSettings =
50
40
  options.getMap("bannerSettings")?.bannerSettingsFromMap(assetManager)
51
- val styleSettings =
52
- options.getMap("styleSettings")?.firstLayerStyleSettingsFromMap(assetManager)
53
-
54
- usercentricsProxy.showFirstLayer(
55
- currentActivity!!,
56
- layout,
57
- bannerSettings,
58
- styleSettings,
59
- promise
60
- )
41
+ usercentricsProxy.showFirstLayer(currentActivity!!, layout, bannerSettings, promise)
61
42
 
62
43
  } catch (e: Exception) {
63
44
  promise.reject(e)
@@ -73,15 +54,7 @@ internal class RNUsercentricsModule(
73
54
 
74
55
  val bannerSettings =
75
56
  options.getMap("bannerSettings")?.bannerSettingsFromMap(assetManager)
76
- val showCloseButton = options.getBoolean("showCloseButton")
77
-
78
-
79
- UsercentricsBanner(currentActivity!!, bannerSettings).showSecondLayer(
80
- showCloseButton
81
- ) {
82
- promise.resolve(it?.toWritableMap())
83
- }
84
-
57
+ usercentricsProxy.showSecondLayer(currentActivity!!, bannerSettings, promise)
85
58
  } catch (e: Exception) {
86
59
  promise.reject(e)
87
60
  }
@@ -97,11 +70,6 @@ internal class RNUsercentricsModule(
97
70
  })
98
71
  }
99
72
 
100
- @ReactMethod
101
- fun getTCFString(promise: Promise) {
102
- promise.resolve(usercentricsProxy.instance.getTCString())
103
- }
104
-
105
73
  @ReactMethod
106
74
  fun getControllerId(promise: Promise) {
107
75
  promise.resolve(usercentricsProxy.instance.getControllerId())
@@ -124,7 +92,9 @@ internal class RNUsercentricsModule(
124
92
 
125
93
  @ReactMethod
126
94
  fun getTCFData(promise: Promise) {
127
- promise.resolve(usercentricsProxy.instance.getTCFData().serialize())
95
+ usercentricsProxy.instance.getTCFData {
96
+ promise.resolve(it.serialize())
97
+ }
128
98
  }
129
99
 
130
100
  @ReactMethod
@@ -226,4 +196,4 @@ internal class RNUsercentricsModule(
226
196
  fun reset() {
227
197
  usercentricsProxy.reset()
228
198
  }
229
- }
199
+ }
@@ -2,38 +2,19 @@ package com.usercentrics.reactnativeusercentrics.api
2
2
 
3
3
  import android.app.Activity
4
4
  import android.content.Context
5
- import android.content.Intent
6
- import android.util.Log
7
5
  import com.facebook.react.bridge.Promise
8
- import com.facebook.react.bridge.ReadableMap
9
- import com.usercentrics.reactnativeusercentrics.extensions.bannerSettingsFromMap
10
- import com.usercentrics.reactnativeusercentrics.extensions.firstLayerStyleSettingsFromMap
11
6
  import com.usercentrics.reactnativeusercentrics.extensions.toWritableMap
12
- import com.usercentrics.reactnativeusercentrics.extensions.usercentricsLayoutFromEnumString
13
7
  import com.usercentrics.sdk.*
14
8
  import com.usercentrics.sdk.errors.UsercentricsError
15
- import java.lang.Exception
16
9
 
17
10
  interface UsercentricsProxy {
11
+
18
12
  val instance: UsercentricsSDK
19
13
 
20
14
  fun initialize(context: Context, options: UsercentricsOptions)
21
-
22
- fun isReady(
23
- onSuccess: (UsercentricsReadyStatus) -> Unit,
24
- onFailure: (UsercentricsError) -> Unit
25
- )
26
-
27
- fun showFirstLayer(
28
- activity: Activity,
29
- layout: UsercentricsLayout,
30
- bannerSettings: BannerSettings?,
31
- firstLayerStyleSettings: FirstLayerStyleSettings?,
32
- promise: Promise
33
- )
34
-
35
- fun showSecondLayer()
36
-
15
+ fun isReady(onSuccess: (UsercentricsReadyStatus) -> Unit, onFailure: (UsercentricsError) -> Unit)
16
+ fun showFirstLayer(activity: Activity, layout: UsercentricsLayout, bannerSettings: BannerSettings?, promise: Promise)
17
+ fun showSecondLayer(activity: Activity, bannerSettings: BannerSettings?, promise: Promise)
37
18
  fun reset()
38
19
  }
39
20
 
@@ -50,30 +31,19 @@ internal class UsercentricsProxyImpl : UsercentricsProxy {
50
31
  }
51
32
  }
52
33
 
53
- override fun isReady(
54
- onSuccess: (UsercentricsReadyStatus) -> Unit,
55
- onFailure: (UsercentricsError) -> Unit
56
- ) = Usercentrics.isReady(onSuccess, onFailure)
34
+ override fun isReady(onSuccess: (UsercentricsReadyStatus) -> Unit, onFailure: (UsercentricsError) -> Unit) = Usercentrics.isReady(onSuccess, onFailure)
57
35
 
58
- override fun showFirstLayer(
59
- activity: Activity,
60
- layout: UsercentricsLayout,
61
- bannerSettings: BannerSettings?,
62
- firstLayerStyleSettings: FirstLayerStyleSettings?,
63
- promise: Promise
64
- ) {
65
- UsercentricsBanner(activity, bannerSettings).showFirstLayer(
66
- layout,
67
- firstLayerStyleSettings
68
- ) {
36
+ override fun showFirstLayer(activity: Activity, layout: UsercentricsLayout, bannerSettings: BannerSettings?, promise: Promise) {
37
+ UsercentricsBanner(activity, bannerSettings).showFirstLayer(layout) {
69
38
  promise.resolve(it?.toWritableMap())
70
39
  }
71
40
  }
72
41
 
73
- override fun showSecondLayer() {
74
-
42
+ override fun showSecondLayer(activity: Activity, bannerSettings: BannerSettings?, promise: Promise) {
43
+ UsercentricsBanner(activity, bannerSettings).showSecondLayer {
44
+ promise.resolve(it?.toWritableMap())
45
+ }
75
46
  }
76
47
 
77
48
  override fun reset() = Usercentrics.reset()
78
-
79
- }
49
+ }
@@ -5,6 +5,7 @@ import com.usercentrics.ccpa.CCPAData
5
5
 
6
6
  internal fun CCPAData.serialize(): WritableMap {
7
7
  return mapOf(
8
+ "uspString" to toUSPString(),
8
9
  "version" to version,
9
10
  "noticeGiven" to noticeGiven,
10
11
  "optedOut" to optedOut,
@@ -20,9 +20,16 @@ internal fun ReadableMap.bannerSettingsFromMap(assetManager: AssetManager): Bann
20
20
  val customFont = getMap("font")
21
21
  val customLogo = getMap("logo")
22
22
 
23
+ val rawFirstLayerStyleSettings = getMap("firstLayerSettings")
24
+ val rawSecondLayerStyleSettings = getMap("secondLayerSettings")
25
+ val rawLegalLinkSettings = getString("links")
26
+
23
27
  return BannerSettings(
24
- customFont?.bannerFontFromMap(assetManager),
25
- customLogo?.bannerLogoFromMap()
28
+ font = customFont?.bannerFontFromMap(assetManager),
29
+ logo = customLogo?.bannerLogoFromMap(),
30
+ firstLayerSettings = rawFirstLayerStyleSettings?.firstLayerStyleSettingsFromMap(assetManager),
31
+ secondLayerSettings = rawSecondLayerStyleSettings?.secondLayerStyleSettingsFromMap(assetManager),
32
+ links = rawLegalLinkSettings?.legalLinksFromEnumString()
26
33
  )
27
34
  }
28
35
 
@@ -146,6 +153,23 @@ internal fun String.deserializeButtonType(): ButtonType {
146
153
  return ButtonType.valueOf(this)
147
154
  }
148
155
 
156
+ internal fun ReadableMap.secondLayerStyleSettingsFromMap(assetManager: AssetManager): SecondLayerStyleSettings {
157
+ return SecondLayerStyleSettings(
158
+ buttonLayout = getMap("buttonLayout")?.buttonLayoutFromMap(assetManager),
159
+ showCloseButton = getBoolean("showCloseButton"),
160
+ )
161
+ }
162
+
163
+ internal fun String?.legalLinksFromEnumString(): LegalLinksSettings? {
164
+ return when (this) {
165
+ "BOTH" -> LegalLinksSettings.BOTH
166
+ "NONE" -> LegalLinksSettings.NONE
167
+ "FIRST_LAYER_ONLY" -> LegalLinksSettings.FIRST_LAYER_ONLY
168
+ "SECOND_LAYER_ONLY" -> LegalLinksSettings.SECOND_LAYER_ONLY
169
+ else -> null
170
+ }
171
+ }
172
+
149
173
  @ColorInt
150
174
  internal fun String.deserializeColor(): Int? {
151
175
  val colorString: String =
@@ -10,7 +10,8 @@ internal fun TCFData.serialize(): WritableMap {
10
10
  "specialFeatures" to specialFeatures.map { it.serialize() },
11
11
  "specialPurposes" to specialPurposes.map { it.serialize() },
12
12
  "stacks" to stacks.map { it.serialize() },
13
- "vendors" to vendors.map { it.serialize() }
13
+ "vendors" to vendors.map { it.serialize() },
14
+ "tcString" to tcString
14
15
  ).toWritableMap()
15
16
  }
16
17
 
@@ -2,6 +2,7 @@ package com.usercentrics.reactnativeusercentrics.extensions
2
2
 
3
3
  import com.facebook.react.bridge.ReadableMap
4
4
  import com.usercentrics.sdk.UsercentricsOptions
5
+ import com.usercentrics.sdk.models.common.NetworkMode
5
6
  import com.usercentrics.sdk.models.common.UsercentricsLoggerLevel
6
7
 
7
8
  internal fun ReadableMap.usercentricsOptionsFromMap(): UsercentricsOptions? {
@@ -29,6 +30,17 @@ internal fun ReadableMap.usercentricsOptionsFromMap(): UsercentricsOptions? {
29
30
  usercentricsOptions.defaultLanguage = it
30
31
  }
31
32
 
33
+ getIntOrNull("networkMode")?.let {
34
+ usercentricsOptions.networkMode = when (it) {
35
+ 0 -> NetworkMode.WORLD
36
+ 1 -> NetworkMode.EU
37
+ else -> {
38
+ assert(false)
39
+ NetworkMode.WORLD
40
+ }
41
+ }
42
+ }
43
+
32
44
  usercentricsOptions
33
45
  }
34
46
  }
@@ -5,8 +5,21 @@ extension BannerSettings {
5
5
  init?(from dictionary: NSDictionary?) {
6
6
  guard let dictionary = dictionary else { return nil }
7
7
 
8
- self.init(font: BannerFontHolder(from: dictionary["font"] as? NSDictionary)?.font,
9
- logo: UIImage(from: dictionary["logo"] as? NSDictionary))
8
+ let bannerFontHolder = BannerFontHolder(from: dictionary["font"] as? NSDictionary)
9
+
10
+ let firstLayerStyleSettingsDict = dictionary["firstLayerSettings"] as? NSDictionary
11
+ let firstLayerSettings = FirstLayerStyleSettings(from: firstLayerStyleSettingsDict, bannerFontHolder: bannerFontHolder)
12
+
13
+ let secondLayerStyleSettingsDict = dictionary["secondLayerSettings"] as? NSDictionary
14
+ let secondLayerSettings = SecondLayerStyleSettings(from: secondLayerStyleSettingsDict, bannerFontHolder: bannerFontHolder)
15
+
16
+ let links = LegalLinksSettings.from(enumString: dictionary["links"] as? String)
17
+
18
+ self.init(font: bannerFontHolder?.font,
19
+ logo: UIImage(from: dictionary["logo"] as? NSDictionary),
20
+ links: links,
21
+ firstLayerSettings: firstLayerSettings,
22
+ secondLayerSettings: secondLayerSettings)
10
23
  }
11
24
  }
12
25
 
@@ -62,6 +75,14 @@ extension FirstLayerStyleSettings {
62
75
  }
63
76
  }
64
77
 
78
+ extension SecondLayerStyleSettings {
79
+ init?(from dictionary: NSDictionary?, bannerFontHolder: BannerFontHolder?) {
80
+ guard let dictionary = dictionary else { return nil }
81
+
82
+ self.init(buttonLayout: ButtonLayout.from(dictionary: dictionary["buttonLayout"] as? NSDictionary, fallbackFont: bannerFontHolder?.boldFont),
83
+ showCloseButton: dictionary["showCloseButton"] as? Bool)
84
+ }
85
+ }
65
86
 
66
87
  extension HeaderImageSettings {
67
88
  static func from(dictionary: NSDictionary?) -> HeaderImageSettings? {
@@ -225,3 +246,22 @@ extension NSTextAlignment {
225
246
  }
226
247
  }
227
248
  }
249
+
250
+ extension LegalLinksSettings {
251
+ static func from(enumString: String?) -> LegalLinksSettings? {
252
+ guard let enumString = enumString else { return nil }
253
+
254
+ switch enumString {
255
+ case "BOTH":
256
+ return .both
257
+ case "FIRST_LAYER_ONLY":
258
+ return .firstLayerOnly
259
+ case "NONE":
260
+ return LegalLinksSettings.none
261
+ case "SECOND_LAYER_ONLY":
262
+ return .secondLayerOnly
263
+ default:
264
+ return nil
265
+ }
266
+ }
267
+ }
@@ -4,6 +4,7 @@ import Usercentrics
4
4
  extension CCPAData {
5
5
  func toDictionary() -> NSDictionary {
6
6
  return [
7
+ "uspString": self.toUSPString(),
7
8
  "version": self.version,
8
9
  "noticeGiven": self.noticeGiven?.boolValue as Any,
9
10
  "optedOut": self.optedOut?.boolValue as Any,
@@ -2,7 +2,7 @@ import Foundation
2
2
  import Usercentrics
3
3
 
4
4
  public extension UsercentricsOptions {
5
- convenience init?(from dictionary: NSDictionary) {
5
+ static func initialize(from dictionary: NSDictionary) -> UsercentricsOptions? {
6
6
  guard let settingsId = dictionary["settingsId"] as? String else {
7
7
  return nil
8
8
  }
@@ -25,11 +25,11 @@ public extension UsercentricsOptions {
25
25
  options.version = version
26
26
  }
27
27
 
28
- self.init(settingsId: settingsId,
29
- defaultLanguage: options.defaultLanguage,
30
- version: options.version,
31
- timeoutMillis: options.timeoutMillis,
32
- loggerLevel: options.loggerLevel)
28
+ if let networkModeValue = dictionary["networkMode"] as? Int {
29
+ options.networkMode = NetworkMode.initialize(from: networkModeValue)
30
+ }
31
+
32
+ return options
33
33
  }
34
34
  }
35
35
 
@@ -47,3 +47,17 @@ public extension UsercentricsLoggerLevel {
47
47
  }
48
48
  }
49
49
  }
50
+
51
+ public extension NetworkMode {
52
+ static func initialize(from value: Int) -> NetworkMode {
53
+ switch value {
54
+ case 0:
55
+ return NetworkMode.world
56
+ case 1:
57
+ return NetworkMode.eu
58
+ default:
59
+ assert(false)
60
+ return NetworkMode.world
61
+ }
62
+ }
63
+ }
@@ -11,21 +11,18 @@ public protocol UsercentricsManager {
11
11
  func showFirstLayer(bannerSettings: BannerSettings?,
12
12
  hostView: UIViewController,
13
13
  layout: UsercentricsLayout,
14
- settings: FirstLayerStyleSettings?,
15
14
  dismissViewHandler: @escaping (UsercentricsConsentUserResponse) -> Void)
16
15
 
17
16
  func showSecondLayer(bannerSettings: BannerSettings?,
18
17
  hostView: UIViewController,
19
- showCloseButton: Bool,
20
18
  dismissViewHandler: @escaping (UsercentricsConsentUserResponse) -> Void)
21
19
 
22
- func getTCString() -> String
23
20
  func getControllerId() -> String
24
21
  func getConsents() -> [UsercentricsServiceConsent]
25
22
  func getCMPData() -> UsercentricsCMPData
26
23
  func getUserSessionData() -> String
27
24
  func getUSPData() -> CCPAData
28
- func getTCFData() -> TCFData
25
+ func getTCFData(callback: @escaping (TCFData) -> Void)
29
26
 
30
27
  func changeLanguage(language: String, onSuccess: @escaping (() -> Void), onFailure: @escaping ((Error) -> Void))
31
28
 
@@ -53,15 +50,6 @@ final class UsercentricsManagerImplementation: UsercentricsManager {
53
50
  }
54
51
 
55
52
  func configure(options: UsercentricsOptions) {
56
- var isConfigured: Bool = false
57
- isReady { _ in
58
- isConfigured = true
59
- } onFailure: { _ in
60
- isConfigured = true
61
- }
62
-
63
- guard !isConfigured else { return }
64
-
65
53
  UsercentricsCore.configure(options: options)
66
54
  }
67
55
 
@@ -72,31 +60,22 @@ final class UsercentricsManagerImplementation: UsercentricsManager {
72
60
  func showFirstLayer(bannerSettings: BannerSettings?,
73
61
  hostView: UIViewController,
74
62
  layout: UsercentricsLayout,
75
- settings: FirstLayerStyleSettings?,
76
63
  dismissViewHandler: @escaping (UsercentricsConsentUserResponse) -> Void) {
77
64
  UsercentricsBanner(bannerSettings: bannerSettings).showFirstLayer(hostView: hostView,
78
65
  layout: layout,
79
- settings: settings,
80
66
  completionHandler: dismissViewHandler)
81
67
  }
82
68
 
83
69
  func showSecondLayer(bannerSettings: BannerSettings?,
84
70
  hostView: UIViewController,
85
- showCloseButton: Bool,
86
71
  dismissViewHandler: @escaping (UsercentricsConsentUserResponse) -> Void) {
87
- UsercentricsBanner(bannerSettings: bannerSettings).showSecondLayer(hostView: hostView,
88
- showCloseButton: showCloseButton,
89
- completionHandler: dismissViewHandler)
72
+ UsercentricsBanner(bannerSettings: bannerSettings).showSecondLayer(hostView: hostView, completionHandler: dismissViewHandler)
90
73
  }
91
74
 
92
75
  func restoreUserSession(controllerId: String, onSuccess: @escaping ((UsercentricsReadyStatus) -> Void), onFailure: @escaping ((Error) -> Void)) {
93
76
  UsercentricsCore.shared.restoreUserSession(controllerId: controllerId, onSuccess: onSuccess, onFailure: onFailure)
94
77
  }
95
78
 
96
- func getTCString() -> String {
97
- return UsercentricsCore.shared.getTCString()
98
- }
99
-
100
79
  func getControllerId() -> String {
101
80
  return UsercentricsCore.shared.getControllerId()
102
81
  }
@@ -117,8 +96,8 @@ final class UsercentricsManagerImplementation: UsercentricsManager {
117
96
  return UsercentricsCore.shared.getUSPData()
118
97
  }
119
98
 
120
- func getTCFData() -> TCFData {
121
- return UsercentricsCore.shared.getTCFData()
99
+ func getTCFData(callback: @escaping (TCFData) -> Void) {
100
+ UsercentricsCore.shared.getTCFData(callback: callback)
122
101
  }
123
102
 
124
103
  func changeLanguage(language: String, onSuccess: @escaping (() -> Void), onFailure: @escaping ((Error) -> Void)) {