@usercentrics/react-native-sdk 2.0.4-rc1 → 2.2.1
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.
- package/README.md +2 -0
- package/android/build.gradle +1 -1
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/RNUsercentricsModuleTest.kt +41 -2
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/api/FakeUsercentricsProxy.kt +23 -1
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetCMPDataMock.kt +2 -1
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetConsentsMock.kt +19 -1
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetTCFDataMock.kt +2 -0
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/SaveDecisionsForTCFMock.kt +18 -1
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/SaveDecisionsMock.kt +0 -1
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/ShowFirstLayerMock.kt +27 -0
- package/android/src/main/java/com/usercentrics/reactnativeusercentrics/RNUsercentricsModule.kt +44 -0
- package/android/src/main/java/com/usercentrics/reactnativeusercentrics/api/UsercentricsProxy.kt +42 -1
- package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/FirstLayerOptionsExtensions.kt +160 -0
- package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/TCFDataExtensions.kt +1 -0
- package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/UsercentricsServiceConsentExtensions.kt +21 -0
- package/ios/Extensions/BannerSettings+Dict.swift +180 -0
- package/ios/Extensions/TCFData+Dict.swift +2 -1
- package/ios/Extensions/UIColor+Extensions.swift +52 -0
- package/ios/Extensions/UIFont+UsercentricsFontDict.swift +15 -0
- package/ios/Extensions/UIImage+UsercentricsLogoDict.swift +14 -0
- package/ios/Extensions/UsercentricsCMPData+Dict.swift +1 -1
- package/ios/Extensions/UsercentricsServiceConsents+Dict.swift +14 -0
- package/ios/Extensions/UsercentricsUISettings+Dict.swift +1 -0
- package/ios/Manager/UsercentricsManager.swift +33 -0
- package/ios/RNUsercentricsModule.m +8 -0
- package/ios/RNUsercentricsModule.swift +91 -28
- package/ios/RNUsercentricsModule.xcodeproj/project.pbxproj +16 -0
- package/lib/Usercentrics.d.ts +6 -1
- package/lib/Usercentrics.js +11 -0
- package/lib/Usercentrics.js.map +1 -1
- package/lib/models/BannerSettings.d.ts +6 -0
- package/lib/models/BannerSettings.js +7 -0
- package/lib/models/BannerSettings.js.map +1 -0
- package/lib/models/FirstLayerOptions.d.ts +82 -0
- package/lib/models/FirstLayerOptions.js +104 -0
- package/lib/models/FirstLayerOptions.js.map +1 -0
- package/lib/models/SecondLayerOptions.d.ts +6 -0
- package/lib/models/SecondLayerOptions.js +7 -0
- package/lib/models/SecondLayerOptions.js.map +1 -0
- package/lib/models/TCFData.d.ts +9 -8
- package/lib/models/TCFData.js +2 -1
- package/lib/models/TCFData.js.map +1 -1
- package/lib/models/UsercentricsServiceConsent.d.ts +9 -1
- package/lib/models/UsercentricsServiceConsent.js +10 -1
- package/lib/models/UsercentricsServiceConsent.js.map +1 -1
- package/lib/models/UsercentricsUIOptions.d.ts +2 -1
- package/lib/models/UsercentricsUIOptions.js +2 -1
- package/lib/models/UsercentricsUIOptions.js.map +1 -1
- package/lib/models/index.d.ts +3 -0
- package/lib/models/index.js +3 -0
- package/lib/models/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import UsercentricsUI
|
|
3
|
+
|
|
4
|
+
extension BannerSettings {
|
|
5
|
+
init?(from dictionary: NSDictionary?) {
|
|
6
|
+
guard let dictionary = dictionary else { return nil }
|
|
7
|
+
|
|
8
|
+
self.init(font: UIFont(from: dictionary["font"] as? NSDictionary),
|
|
9
|
+
logo: UIImage(from: dictionary["logo"] as? NSDictionary))
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
extension FirstLayerStyleSettings {
|
|
14
|
+
init?(from dictionary: NSDictionary?) {
|
|
15
|
+
guard let dictionary = dictionary else { return nil }
|
|
16
|
+
|
|
17
|
+
self.init(headerImage: HeaderImageSettings.from(dictionary: dictionary["headerImage"] as? NSDictionary),
|
|
18
|
+
title: TitleSettings(from: dictionary["title"] as? NSDictionary),
|
|
19
|
+
message: MessageSettings(from: dictionary["message"] as? NSDictionary),
|
|
20
|
+
buttonLayout: ButtonLayout.from(dictionary: dictionary["buttonLayout"] as? NSDictionary),
|
|
21
|
+
backgroundColor: UIColor(unsafeHex: dictionary["backgroundColorHex"] as? String),
|
|
22
|
+
cornerRadius: dictionary["cornerRadius"] as? CGFloat,
|
|
23
|
+
overlayColor: UIColor(unsafeHex: dictionary["overlayColorHex"] as? String))
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
extension HeaderImageSettings {
|
|
29
|
+
static func from(dictionary: NSDictionary?) -> HeaderImageSettings? {
|
|
30
|
+
guard let dictionary = dictionary else { return nil }
|
|
31
|
+
|
|
32
|
+
if let isHidden = dictionary["isHidden"] as? Bool, isHidden {
|
|
33
|
+
return .hidden
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let logoDict = dictionary["image"] as? NSDictionary
|
|
37
|
+
let logo = UIImage(from: logoDict)
|
|
38
|
+
|
|
39
|
+
if let isExtended = dictionary["isExtended"] as? Bool, isExtended {
|
|
40
|
+
return .extended(image: logo)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
let logoUrlString = logoDict?["logoUrl"] as? String
|
|
44
|
+
|
|
45
|
+
return .logo(settings: LogoSettings(image: logo,
|
|
46
|
+
url: URL(string: logoUrlString ?? ""),
|
|
47
|
+
position: SectionPosition.from(enumString: dictionary["alignment"] as? String),
|
|
48
|
+
height: dictionary["height"] as? CGFloat))
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
extension TitleSettings {
|
|
53
|
+
init?(from dictionary: NSDictionary?) {
|
|
54
|
+
guard let dictionary = dictionary else { return nil }
|
|
55
|
+
|
|
56
|
+
self.init(font: UIFont(from: dictionary["font"] as? NSDictionary),
|
|
57
|
+
textColor: UIColor(unsafeHex: dictionary["textColorHex"] as? String ?? ""),
|
|
58
|
+
textAlignment: NSTextAlignment.from(enumString: dictionary["textAlignment"] as? String))
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
extension MessageSettings {
|
|
64
|
+
init?(from dictionary: NSDictionary?) {
|
|
65
|
+
guard let dictionary = dictionary else { return nil }
|
|
66
|
+
|
|
67
|
+
self.init(font: UIFont(from: dictionary["font"] as? NSDictionary),
|
|
68
|
+
textColor: UIColor(unsafeHex: dictionary["textColorHex"] as? String ?? ""),
|
|
69
|
+
textAlignment: NSTextAlignment.from(enumString: dictionary["textAlignment"] as? String),
|
|
70
|
+
linkTextColor: UIColor(unsafeHex: dictionary["linkTextColorHex"] as? String ?? ""),
|
|
71
|
+
linkTextUnderline: dictionary["linkTextUnderline"] as? Bool ?? true)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
extension ButtonLayout {
|
|
76
|
+
static func from(dictionary: NSDictionary?) -> ButtonLayout? {
|
|
77
|
+
guard let dictionary = dictionary else { return nil }
|
|
78
|
+
|
|
79
|
+
let layoutDict = dictionary["layout"] as? String
|
|
80
|
+
let buttons = (dictionary["buttons"] as? [[NSDictionary]]) ?? []
|
|
81
|
+
|
|
82
|
+
switch layoutDict {
|
|
83
|
+
case "ROW":
|
|
84
|
+
return .row(buttons: buttons.flatMap { $0 }.compactMap { ButtonSettings(from: $0) })
|
|
85
|
+
case "COLUMN":
|
|
86
|
+
return .column(buttons: buttons.flatMap { $0 }.compactMap { ButtonSettings(from: $0) })
|
|
87
|
+
case "GRID":
|
|
88
|
+
let gridButtons = buttons.map { $0.compactMap { button in ButtonSettings(from: button) }}
|
|
89
|
+
return .grid(buttons: gridButtons)
|
|
90
|
+
default:
|
|
91
|
+
break
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return nil
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
extension ButtonSettings {
|
|
99
|
+
init?(from dictionary: NSDictionary?) {
|
|
100
|
+
guard
|
|
101
|
+
let dictionary = dictionary,
|
|
102
|
+
let buttonTypeDict = dictionary["buttonType"] as? String,
|
|
103
|
+
let buttonType = ButtonType.from(enumString: buttonTypeDict)
|
|
104
|
+
else { return nil }
|
|
105
|
+
|
|
106
|
+
self.init(type: buttonType,
|
|
107
|
+
font: UIFont(from: dictionary["font"] as? NSDictionary),
|
|
108
|
+
textColor: UIColor(unsafeHex: dictionary["textColorHex"] as? String),
|
|
109
|
+
backgroundColor: UIColor(unsafeHex: dictionary["backgroundColorHex"] as? String),
|
|
110
|
+
cornerRadius: dictionary["cornerRadius"] as? CGFloat)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
extension ButtonType {
|
|
115
|
+
static func from(enumString: String) -> ButtonType? {
|
|
116
|
+
switch enumString {
|
|
117
|
+
case "ACCEPT_ALL":
|
|
118
|
+
return .acceptAll
|
|
119
|
+
case "DENY_ALL":
|
|
120
|
+
return .denyAll
|
|
121
|
+
case "MORE":
|
|
122
|
+
return .more
|
|
123
|
+
case "SAVE":
|
|
124
|
+
return .save
|
|
125
|
+
default:
|
|
126
|
+
return nil
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
extension UsercentricsLayout {
|
|
132
|
+
static func from(enumString: String) -> UsercentricsLayout? {
|
|
133
|
+
switch enumString {
|
|
134
|
+
case "FULL":
|
|
135
|
+
return .full
|
|
136
|
+
case "SHEET":
|
|
137
|
+
return .sheet
|
|
138
|
+
case "POPUP_CENTER":
|
|
139
|
+
return .popup(position: .center)
|
|
140
|
+
case "POPUP_BOTTOM":
|
|
141
|
+
return .popup(position: .bottom)
|
|
142
|
+
default:
|
|
143
|
+
return nil
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
extension SectionPosition {
|
|
149
|
+
static func from(enumString: String?) -> SectionPosition? {
|
|
150
|
+
guard let enumString = enumString else { return nil }
|
|
151
|
+
|
|
152
|
+
switch enumString {
|
|
153
|
+
case "CENTER":
|
|
154
|
+
return .center
|
|
155
|
+
case "END":
|
|
156
|
+
return .right
|
|
157
|
+
case "START":
|
|
158
|
+
return .left
|
|
159
|
+
default:
|
|
160
|
+
return nil
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
extension NSTextAlignment {
|
|
166
|
+
static func from(enumString: String?) -> NSTextAlignment? {
|
|
167
|
+
guard let enumString = enumString else { return nil }
|
|
168
|
+
|
|
169
|
+
switch enumString {
|
|
170
|
+
case "CENTER":
|
|
171
|
+
return .center
|
|
172
|
+
case "RIGHT":
|
|
173
|
+
return .right
|
|
174
|
+
case "LEFT":
|
|
175
|
+
return .left
|
|
176
|
+
default:
|
|
177
|
+
return nil
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -102,7 +102,8 @@ extension TCFVendor {
|
|
|
102
102
|
"usesNonCookieAccess" : usesNonCookieAccess,
|
|
103
103
|
"deviceStorageDisclosureUrl" : deviceStorageDisclosureUrl as Any,
|
|
104
104
|
"usesCookies" : usesCookies,
|
|
105
|
-
"cookieRefresh" : cookieRefresh?.boolValue as Any
|
|
105
|
+
"cookieRefresh" : cookieRefresh?.boolValue as Any,
|
|
106
|
+
"dataSharedOutsideEU": dataSharedOutsideEU?.boolValue as Any
|
|
106
107
|
]
|
|
107
108
|
}
|
|
108
109
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
extension UIColor {
|
|
4
|
+
convenience init?(unsafeHex: String?) {
|
|
5
|
+
guard let unsafeHex = unsafeHex else { return nil }
|
|
6
|
+
if unsafeHex.hasPrefix("#") {
|
|
7
|
+
self.init(hex: unsafeHex)
|
|
8
|
+
} else {
|
|
9
|
+
self.init(hex: "#\(unsafeHex)")
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
convenience init?(hex: String) {
|
|
14
|
+
let r, g, b, a: CGFloat
|
|
15
|
+
|
|
16
|
+
if hex.hasPrefix("#") {
|
|
17
|
+
let start = hex.index(hex.startIndex, offsetBy: 1)
|
|
18
|
+
let hexColor = String(hex[start...])
|
|
19
|
+
|
|
20
|
+
if hexColor.count == 8 {
|
|
21
|
+
let scanner = Scanner(string: hexColor)
|
|
22
|
+
var hexNumber: UInt64 = 0
|
|
23
|
+
|
|
24
|
+
if scanner.scanHexInt64(&hexNumber) {
|
|
25
|
+
r = CGFloat((hexNumber & 0xff000000) >> 24) / 255
|
|
26
|
+
g = CGFloat((hexNumber & 0x00ff0000) >> 16) / 255
|
|
27
|
+
b = CGFloat((hexNumber & 0x0000ff00) >> 8) / 255
|
|
28
|
+
a = CGFloat(hexNumber & 0x000000ff) / 255
|
|
29
|
+
|
|
30
|
+
self.init(red: r, green: g, blue: b, alpha: a)
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if hexColor.count == 6 {
|
|
36
|
+
let scanner = Scanner(string: hexColor)
|
|
37
|
+
var hexNumber: UInt64 = 0
|
|
38
|
+
|
|
39
|
+
if scanner.scanHexInt64(&hexNumber) {
|
|
40
|
+
r = CGFloat((hexNumber & 0xff0000) >> 16) / 255
|
|
41
|
+
g = CGFloat((hexNumber & 0x00ff00) >> 8) / 255
|
|
42
|
+
b = CGFloat(hexNumber & 0x0000ff) / 255
|
|
43
|
+
|
|
44
|
+
self.init(red: r, green: g, blue: b, alpha: 1.0)
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return nil
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
extension UIFont {
|
|
5
|
+
convenience init?(from dictionary: NSDictionary?) {
|
|
6
|
+
guard let dictionary = dictionary else { return nil }
|
|
7
|
+
|
|
8
|
+
if let customFontName = dictionary["fontName"] as? String,
|
|
9
|
+
let customFontSize = dictionary["fontSize"] as? CGFloat {
|
|
10
|
+
self.init(name: customFontName, size: customFontSize)
|
|
11
|
+
} else {
|
|
12
|
+
return nil
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
extension UIImage {
|
|
4
|
+
convenience init?(from dictionary: NSDictionary?) {
|
|
5
|
+
guard
|
|
6
|
+
let dictionary = dictionary,
|
|
7
|
+
let logoName = dictionary["logoName"] as? String
|
|
8
|
+
else {
|
|
9
|
+
return nil
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
self.init(named: logoName)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -22,7 +22,7 @@ extension UsercentricsSettings {
|
|
|
22
22
|
"displayOnlyForEU" : self.displayOnlyForEU,
|
|
23
23
|
"urlConsentInfo" : self.urlConsentInfo,
|
|
24
24
|
"updatedAt" : self.updatedAt as Any,
|
|
25
|
-
"secondLayer" : self.secondLayer
|
|
25
|
+
"secondLayer" : self.secondLayer.toDictionary() as Any,
|
|
26
26
|
"cookiePolicyUrl": self.cookiePolicyUrl as Any,
|
|
27
27
|
"tcf2": self.tcf2?.toDictionary() as Any,
|
|
28
28
|
"ccpa": self.ccpa?.toDictionary() as Any,
|
|
@@ -14,6 +14,8 @@ public extension UsercentricsServiceConsent {
|
|
|
14
14
|
"status": self.status,
|
|
15
15
|
"version": self.version,
|
|
16
16
|
"dataProcessor": self.dataProcessor,
|
|
17
|
+
"isEssential": self.isEssential,
|
|
18
|
+
"history": self.history.toDictionary()
|
|
17
19
|
]
|
|
18
20
|
|
|
19
21
|
if let type = self.type?.ordinal {
|
|
@@ -23,3 +25,15 @@ public extension UsercentricsServiceConsent {
|
|
|
23
25
|
return dict
|
|
24
26
|
}
|
|
25
27
|
}
|
|
28
|
+
|
|
29
|
+
public extension Array where Element == UsercentricsConsentHistoryEntry {
|
|
30
|
+
func toDictionary() -> [NSDictionary] {
|
|
31
|
+
self.map {
|
|
32
|
+
[
|
|
33
|
+
"status": $0.status,
|
|
34
|
+
"type": $0.type.ordinal,
|
|
35
|
+
"timestampInMillis": $0.timestampInMillis
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -9,6 +9,18 @@ public protocol UsercentricsManager {
|
|
|
9
9
|
func restoreUserSession(controllerId: String, onSuccess: @escaping ((UsercentricsReadyStatus) -> Void), onFailure: @escaping ((Error) -> Void))
|
|
10
10
|
|
|
11
11
|
func getPredefinedUI(settings: UsercentricsUISettings?, dismissViewHandler: @escaping (UsercentricsConsentUserResponse) -> Void) -> UIViewController
|
|
12
|
+
|
|
13
|
+
func showFirstLayer(bannerSettings: BannerSettings?,
|
|
14
|
+
hostView: UINavigationController,
|
|
15
|
+
layout: UsercentricsLayout,
|
|
16
|
+
settings: FirstLayerStyleSettings?,
|
|
17
|
+
dismissViewHandler: @escaping (UsercentricsConsentUserResponse) -> Void)
|
|
18
|
+
|
|
19
|
+
func showSecondLayer(bannerSettings: BannerSettings?,
|
|
20
|
+
hostView: UINavigationController,
|
|
21
|
+
showCloseButton: Bool,
|
|
22
|
+
dismissViewHandler: @escaping (UsercentricsConsentUserResponse) -> Void)
|
|
23
|
+
|
|
12
24
|
func getTCString() -> String
|
|
13
25
|
func getControllerId() -> String
|
|
14
26
|
func getConsents() -> [UsercentricsServiceConsent]
|
|
@@ -63,6 +75,27 @@ final class UsercentricsManagerImplementation: UsercentricsManager {
|
|
|
63
75
|
return UsercentricsUserInterface.getPredefinedUI(settings: settings, dismissViewHandler: dismissViewHandler)
|
|
64
76
|
}
|
|
65
77
|
|
|
78
|
+
func showFirstLayer(bannerSettings: BannerSettings?,
|
|
79
|
+
hostView: UINavigationController,
|
|
80
|
+
layout: UsercentricsLayout,
|
|
81
|
+
settings: FirstLayerStyleSettings?,
|
|
82
|
+
dismissViewHandler: @escaping (UsercentricsConsentUserResponse) -> Void) {
|
|
83
|
+
UsercentricsBanner(bannerSettings: bannerSettings).showFirstLayer(hostView: hostView,
|
|
84
|
+
layout: layout,
|
|
85
|
+
settings: settings,
|
|
86
|
+
completionHandler: dismissViewHandler)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
func showSecondLayer(bannerSettings: BannerSettings?,
|
|
90
|
+
hostView: UINavigationController,
|
|
91
|
+
showCloseButton: Bool,
|
|
92
|
+
dismissViewHandler: @escaping (UsercentricsConsentUserResponse) -> Void) {
|
|
93
|
+
UsercentricsBanner(bannerSettings: bannerSettings).showSecondLayer(hostView: hostView,
|
|
94
|
+
showCloseButton: showCloseButton,
|
|
95
|
+
presentationMode: .present,
|
|
96
|
+
completionHandler: dismissViewHandler)
|
|
97
|
+
}
|
|
98
|
+
|
|
66
99
|
func restoreUserSession(controllerId: String, onSuccess: @escaping ((UsercentricsReadyStatus) -> Void), onFailure: @escaping ((Error) -> Void)) {
|
|
67
100
|
UsercentricsCore.shared.restoreUserSession(controllerId: controllerId, onSuccess: onSuccess, onFailure: onFailure)
|
|
68
101
|
}
|
|
@@ -14,6 +14,14 @@ RCT_EXTERN_METHOD(showCMP:(NSDictionary *)dict
|
|
|
14
14
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
15
15
|
reject:(RCTPromiseRejectBlock)reject)
|
|
16
16
|
|
|
17
|
+
RCT_EXTERN_METHOD(showFirstLayer:(NSDictionary *)dict
|
|
18
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
19
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
20
|
+
|
|
21
|
+
RCT_EXTERN_METHOD(showSecondLayer:(NSDictionary *)dict
|
|
22
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
23
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
24
|
+
|
|
17
25
|
RCT_EXTERN_METHOD(restoreUserSession:(NSString *)controllerId
|
|
18
26
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
19
27
|
reject:(RCTPromiseRejectBlock)reject)
|
|
@@ -5,30 +5,30 @@ import UIKit
|
|
|
5
5
|
|
|
6
6
|
@objc(RNUsercentricsModule)
|
|
7
7
|
class RNUsercentricsModule: NSObject, RCTBridgeModule {
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
var usercentricsManager: UsercentricsManager = UsercentricsManagerImplementation()
|
|
10
10
|
var queue: DispatchQueueManager = DispatchQueue.main
|
|
11
11
|
var rootVC: PresentationViewController? = UIApplication.shared.delegate?.window??.rootViewController
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
@objc static func moduleName() -> String! {
|
|
14
14
|
return "RNUsercentricsModule"
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
@objc static func requiresMainQueueSetup() -> Bool {
|
|
18
18
|
return true
|
|
19
19
|
}
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
@objc func configure(_ dict: NSDictionary) -> Void {
|
|
22
22
|
queue.async { [weak self] in
|
|
23
23
|
guard
|
|
24
24
|
let self = self,
|
|
25
25
|
let userOptions = UsercentricsOptions(from: dict)
|
|
26
26
|
else { return }
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
self.usercentricsManager.configure(options: userOptions)
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
@objc func isReady(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
33
33
|
usercentricsManager.isReady { status in
|
|
34
34
|
resolve(status.toDictionary())
|
|
@@ -36,7 +36,7 @@ class RNUsercentricsModule: NSObject, RCTBridgeModule {
|
|
|
36
36
|
reject("usercentrics_reactNative_isReady_error", error.localizedDescription, error)
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
@objc func showCMP(_ dict: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
41
41
|
queue.async { [weak self] in
|
|
42
42
|
guard
|
|
@@ -52,16 +52,79 @@ class RNUsercentricsModule: NSObject, RCTBridgeModule {
|
|
|
52
52
|
resolve(response.toDictionary())
|
|
53
53
|
rootVC.dismiss(animated: true)
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
if #available(iOS 13.0, *) { predefinedUI.isModalInPresentation = true }
|
|
57
57
|
rootVC.present(predefinedUI)
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
|
|
61
|
+
@objc func showFirstLayer(_ dict: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
62
|
+
queue.async { [weak self] in
|
|
63
|
+
guard
|
|
64
|
+
let self = self,
|
|
65
|
+
let rootVC = self.rootVC,
|
|
66
|
+
let layoutString = dict["layout"] as? String,
|
|
67
|
+
let layout = UsercentricsLayout.from(enumString: layoutString)
|
|
68
|
+
else {
|
|
69
|
+
reject("usercentrics_reactNative_showFirstLayer_error", RNUsercentricsModuleError.invalidData.localizedDescription, RNUsercentricsModuleError.invalidData)
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let nav = UINavigationController()
|
|
74
|
+
nav.setNavigationBarHidden(true, animated: false)
|
|
75
|
+
nav.modalPresentationStyle = .overFullScreen
|
|
76
|
+
if #available(iOS 13.0, *) {
|
|
77
|
+
nav.isModalInPresentation = true
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
rootVC.present(nav)
|
|
81
|
+
let bannerSettingsDict = dict["bannerSettings"] as? NSDictionary
|
|
82
|
+
let styleSettingsDict = dict["styleSettings"] as? NSDictionary
|
|
83
|
+
|
|
84
|
+
self.usercentricsManager.showFirstLayer(bannerSettings: BannerSettings(from: bannerSettingsDict),
|
|
85
|
+
hostView: nav,
|
|
86
|
+
layout: layout,
|
|
87
|
+
settings: FirstLayerStyleSettings(from: styleSettingsDict)) { response in
|
|
88
|
+
rootVC.dismiss(animated: true)
|
|
89
|
+
resolve(response.toDictionary())
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@objc func showSecondLayer(_ dict: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
95
|
+
queue.async { [weak self] in
|
|
96
|
+
guard
|
|
97
|
+
let self = self,
|
|
98
|
+
let rootVC = self.rootVC
|
|
99
|
+
else {
|
|
100
|
+
reject("usercentrics_reactNative_showFirstLayer_error", RNUsercentricsModuleError.invalidData.localizedDescription, RNUsercentricsModuleError.invalidData)
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
let bannerSettingsDict = dict["bannerSettings"] as? NSDictionary
|
|
104
|
+
let showCloseButton = (dict["showCloseButton"] as? Bool) ?? false
|
|
105
|
+
|
|
106
|
+
let nav = UINavigationController()
|
|
107
|
+
nav.setNavigationBarHidden(true, animated: false)
|
|
108
|
+
nav.modalPresentationStyle = .overFullScreen
|
|
109
|
+
if #available(iOS 13.0, *) {
|
|
110
|
+
nav.isModalInPresentation = true
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
rootVC.present(nav)
|
|
114
|
+
|
|
115
|
+
self.usercentricsManager.showSecondLayer(bannerSettings: BannerSettings(from: bannerSettingsDict),
|
|
116
|
+
hostView: nav,
|
|
117
|
+
showCloseButton: showCloseButton) { response in
|
|
118
|
+
rootVC.dismiss(animated: true)
|
|
119
|
+
resolve(response.toDictionary())
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
61
124
|
@objc func setCMPId(_ id: Int) -> Void {
|
|
62
125
|
usercentricsManager.setCMPId(id: Int32(id))
|
|
63
126
|
}
|
|
64
|
-
|
|
127
|
+
|
|
65
128
|
@objc func restoreUserSession(_ controllerId: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
66
129
|
usercentricsManager.restoreUserSession(controllerId: controllerId) { status in
|
|
67
130
|
resolve(status.toDictionary())
|
|
@@ -69,35 +132,35 @@ class RNUsercentricsModule: NSObject, RCTBridgeModule {
|
|
|
69
132
|
reject("usercentrics_reactNative_restoreUserSession_error", error.localizedDescription, error)
|
|
70
133
|
}
|
|
71
134
|
}
|
|
72
|
-
|
|
135
|
+
|
|
73
136
|
@objc func getTCFString(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
74
137
|
resolve(usercentricsManager.getTCString())
|
|
75
138
|
}
|
|
76
|
-
|
|
139
|
+
|
|
77
140
|
@objc func getControllerId(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
78
141
|
resolve(usercentricsManager.getControllerId())
|
|
79
142
|
}
|
|
80
|
-
|
|
143
|
+
|
|
81
144
|
@objc func getConsents(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
82
145
|
resolve(usercentricsManager.getConsents().toListOfDictionary())
|
|
83
146
|
}
|
|
84
|
-
|
|
147
|
+
|
|
85
148
|
@objc func getCMPData(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
86
149
|
resolve(usercentricsManager.getCMPData().toDictionary())
|
|
87
150
|
}
|
|
88
|
-
|
|
151
|
+
|
|
89
152
|
@objc func getTCFData(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
90
153
|
resolve(usercentricsManager.getTCFData().toDictionary())
|
|
91
154
|
}
|
|
92
|
-
|
|
155
|
+
|
|
93
156
|
@objc func getUserSessionData(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
94
157
|
resolve(usercentricsManager.getUserSessionData())
|
|
95
158
|
}
|
|
96
|
-
|
|
159
|
+
|
|
97
160
|
@objc func getUSPData(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
98
161
|
resolve(usercentricsManager.getUSPData().toDictionary())
|
|
99
162
|
}
|
|
100
|
-
|
|
163
|
+
|
|
101
164
|
@objc func changeLanguage(_ language: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
102
165
|
usercentricsManager.changeLanguage(language: language) {
|
|
103
166
|
resolve(Void.self)
|
|
@@ -105,7 +168,7 @@ class RNUsercentricsModule: NSObject, RCTBridgeModule {
|
|
|
105
168
|
reject("usercentrics_reactNative_changeLanguage_error", error.localizedDescription, error)
|
|
106
169
|
}
|
|
107
170
|
}
|
|
108
|
-
|
|
171
|
+
|
|
109
172
|
@objc func acceptAllForTCF(_ fromLayer: Int,
|
|
110
173
|
consentType: Int,
|
|
111
174
|
resolve: @escaping RCTPromiseResolveBlock,
|
|
@@ -114,14 +177,14 @@ class RNUsercentricsModule: NSObject, RCTBridgeModule {
|
|
|
114
177
|
consentType: UsercentricsConsentType.initialize(from: consentType))
|
|
115
178
|
resolve(services.toListOfDictionary())
|
|
116
179
|
}
|
|
117
|
-
|
|
180
|
+
|
|
118
181
|
@objc func acceptAll(_ consentType: Int,
|
|
119
182
|
resolve: @escaping RCTPromiseResolveBlock,
|
|
120
183
|
reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
121
184
|
let services = usercentricsManager.acceptAll(consentType: UsercentricsConsentType.initialize(from: consentType))
|
|
122
185
|
resolve(services.toListOfDictionary())
|
|
123
186
|
}
|
|
124
|
-
|
|
187
|
+
|
|
125
188
|
@objc func denyAllForTCF(_ fromLayer: Int,
|
|
126
189
|
consentType: Int,
|
|
127
190
|
resolve: @escaping RCTPromiseResolveBlock,
|
|
@@ -129,30 +192,30 @@ class RNUsercentricsModule: NSObject, RCTBridgeModule {
|
|
|
129
192
|
let services = usercentricsManager.denyAllForTCF(fromLayer: .initialize(from: fromLayer), consentType: .initialize(from: consentType))
|
|
130
193
|
resolve(services.toListOfDictionary())
|
|
131
194
|
}
|
|
132
|
-
|
|
195
|
+
|
|
133
196
|
@objc func denyAll(_ consentType: Int,
|
|
134
197
|
resolve: @escaping RCTPromiseResolveBlock,
|
|
135
198
|
reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
136
199
|
let services = usercentricsManager.denyAll(consentType: .initialize(from: consentType))
|
|
137
200
|
resolve(services.toListOfDictionary())
|
|
138
201
|
}
|
|
139
|
-
|
|
202
|
+
|
|
140
203
|
@objc func saveDecisionsForTCF(_ tcfDecisions: NSDictionary,
|
|
141
204
|
fromLayer: Int,
|
|
142
205
|
serviceDecisions: [NSDictionary],
|
|
143
206
|
consentType: Int,
|
|
144
207
|
resolve: @escaping RCTPromiseResolveBlock,
|
|
145
208
|
reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
146
|
-
|
|
209
|
+
|
|
147
210
|
let services = usercentricsManager.saveDecisionsForTCF(
|
|
148
211
|
tcfDecisions: TCFUserDecisions(from: tcfDecisions),
|
|
149
212
|
fromLayer: .initialize(from: fromLayer),
|
|
150
213
|
serviceDecisions: serviceDecisions.compactMap { UserDecision(from: $0) },
|
|
151
214
|
consentType: .initialize(from: consentType))
|
|
152
215
|
resolve(services.toListOfDictionary())
|
|
153
|
-
|
|
216
|
+
|
|
154
217
|
}
|
|
155
|
-
|
|
218
|
+
|
|
156
219
|
@objc func saveDecisions(_ decisions: [NSDictionary],
|
|
157
220
|
consentType: Int,
|
|
158
221
|
resolve: @escaping RCTPromiseResolveBlock,
|
|
@@ -160,7 +223,7 @@ class RNUsercentricsModule: NSObject, RCTBridgeModule {
|
|
|
160
223
|
let services = usercentricsManager.saveDecisions(decisions: decisions.compactMap { UserDecision.init(from: $0) }, consentType: .initialize(from: consentType))
|
|
161
224
|
resolve(services.toListOfDictionary())
|
|
162
225
|
}
|
|
163
|
-
|
|
226
|
+
|
|
164
227
|
@objc func saveOptOutForCCPA(_ isOptedOut: Bool,
|
|
165
228
|
consentType: Int,
|
|
166
229
|
resolve: @escaping RCTPromiseResolveBlock,
|
|
@@ -168,7 +231,7 @@ class RNUsercentricsModule: NSObject, RCTBridgeModule {
|
|
|
168
231
|
let services = usercentricsManager.saveOptOutForCCPA(isOptedOut: isOptedOut, consentType: .initialize(from: consentType))
|
|
169
232
|
resolve(services.toListOfDictionary())
|
|
170
233
|
}
|
|
171
|
-
|
|
234
|
+
|
|
172
235
|
@objc func reset() -> Void {
|
|
173
236
|
usercentricsManager.reset()
|
|
174
237
|
}
|