@snowplow/react-native-tracker 1.4.0 → 2.0.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 (239) hide show
  1. package/.editorconfig +15 -0
  2. package/.eslintignore +6 -0
  3. package/.gitattributes +3 -0
  4. package/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  6. package/.github/actions/setup/action.yml +28 -0
  7. package/.github/workflows/build.yml +150 -0
  8. package/.github/workflows/deploy.yml +98 -0
  9. package/.github/workflows/e2e-android.yml +121 -0
  10. package/.github/workflows/e2e-ios.yml +90 -0
  11. package/.github/workflows/snyk.yml +21 -0
  12. package/.gitignore +70 -0
  13. package/.npmignore +60 -0
  14. package/.nvmrc +1 -0
  15. package/.watchmanconfig +1 -0
  16. package/.yarnrc +3 -0
  17. package/CHANGELOG +166 -0
  18. package/CONTRIBUTING.md +80 -0
  19. package/README.md +23 -110
  20. package/android/build.gradle +93 -37
  21. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  22. package/android/gradle/wrapper/gradle-wrapper.properties +1 -2
  23. package/android/gradle.properties +5 -2
  24. package/android/gradlew +172 -110
  25. package/android/gradlew.bat +24 -19
  26. package/android/src/main/AndroidManifest.xml +1 -3
  27. package/android/src/main/AndroidManifestNew.xml +2 -0
  28. package/android/src/main/java/com/snowplow/reactnativetracker/ReactNativeTrackerModule.kt +704 -0
  29. package/android/src/main/java/com/snowplow/reactnativetracker/ReactNativeTrackerPackage.kt +17 -0
  30. package/android/src/main/java/com/snowplow/reactnativetracker/util/ConfigUtil.kt +271 -0
  31. package/android/src/main/java/com/snowplow/reactnativetracker/util/EventUtil.kt +213 -0
  32. package/android/src/main/java/com/snowplow/reactnativetracker/util/TrackerVersion.kt +5 -0
  33. package/babel.config.js +3 -0
  34. package/example/.watchmanconfig +1 -0
  35. package/example/Gemfile +6 -0
  36. package/example/android/app/build.gradle +129 -0
  37. package/example/android/app/debug.keystore +0 -0
  38. package/example/android/app/proguard-rules.pro +10 -0
  39. package/example/android/app/src/androidTest/java/com/reactnativetrackerexample/DetoxTest.java +36 -0
  40. package/example/android/app/src/androidTest/java/com/reactnativetrackerexample/DetoxTestAppJUnitRunner.java +21 -0
  41. package/example/android/app/src/debug/AndroidManifest.xml +13 -0
  42. package/example/android/app/src/debug/java/com/reactnativetrackerexample/ReactNativeFlipper.java +75 -0
  43. package/example/android/app/src/main/AndroidManifest.xml +26 -0
  44. package/example/android/app/src/main/java/com/reactnativetrackerexample/MainActivity.java +32 -0
  45. package/example/android/app/src/main/java/com/reactnativetrackerexample/MainApplication.java +62 -0
  46. package/example/android/app/src/main/res/drawable/rn_edit_text_material.xml +36 -0
  47. package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  48. package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  49. package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  50. package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  51. package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  52. package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  53. package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  54. package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  55. package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  56. package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  57. package/example/android/app/src/main/res/values/strings.xml +3 -0
  58. package/example/android/app/src/main/res/values/styles.xml +9 -0
  59. package/example/android/app/src/release/java/com/reactnativetrackerexample/ReactNativeFlipper.java +20 -0
  60. package/example/android/build.gradle +31 -0
  61. package/example/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  62. package/example/android/gradle/wrapper/gradle-wrapper.properties +6 -0
  63. package/example/android/gradle.properties +44 -0
  64. package/example/android/gradlew +244 -0
  65. package/example/android/gradlew.bat +92 -0
  66. package/example/android/settings.gradle +4 -0
  67. package/example/app.json +4 -0
  68. package/example/babel.config.js +17 -0
  69. package/example/detox.config.js +92 -0
  70. package/example/e2e/config.json +10 -0
  71. package/example/e2e/emitEvents.e2e.detox.js +108 -0
  72. package/example/e2e/environment.js +23 -0
  73. package/example/e2e/helpers/microCommands.js +153 -0
  74. package/example/e2e/helpers/microHelpers.js +346 -0
  75. package/example/e2e/helpers/microHelpers.test.js +308 -0
  76. package/example/e2e/helpers/schemas.js +62 -0
  77. package/example/e2e/jest.config.js +16 -0
  78. package/example/e2e/setup.js +4 -0
  79. package/example/e2e/testEvents.micro.test.js +300 -0
  80. package/example/index.js +5 -0
  81. package/example/ios/.xcode.env +11 -0
  82. package/example/ios/Podfile +64 -0
  83. package/example/ios/Podfile.lock +737 -0
  84. package/example/ios/ReactNativeTrackerExample/AppDelegate.h +6 -0
  85. package/example/ios/ReactNativeTrackerExample/AppDelegate.mm +26 -0
  86. package/example/ios/ReactNativeTrackerExample/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
  87. package/example/ios/ReactNativeTrackerExample/Images.xcassets/Contents.json +6 -0
  88. package/example/ios/ReactNativeTrackerExample/Info.plist +55 -0
  89. package/example/ios/ReactNativeTrackerExample/LaunchScreen.storyboard +47 -0
  90. package/example/ios/ReactNativeTrackerExample/main.m +10 -0
  91. package/example/ios/ReactNativeTrackerExample-Bridging-Header.h +3 -0
  92. package/example/ios/ReactNativeTrackerExample.xcodeproj/project.pbxproj +722 -0
  93. package/{ios/RNSnowplowTracker.xcodeproj/xcshareddata/xcschemes/RNSnowplowTracker.xcscheme → example/ios/ReactNativeTrackerExample.xcodeproj/xcshareddata/xcschemes/ReactNativeTrackerExample.xcscheme} +29 -21
  94. package/example/ios/ReactNativeTrackerExample.xcworkspace/contents.xcworkspacedata +10 -0
  95. package/example/ios/ReactNativeTrackerExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  96. package/example/ios/ReactNativeTrackerExampleTests/Info.plist +24 -0
  97. package/example/ios/ReactNativeTrackerExampleTests/ReactNativeTrackerExampleTests.m +66 -0
  98. package/example/metro.config.js +45 -0
  99. package/example/package.json +54 -0
  100. package/example/react-native.config.js +10 -0
  101. package/example/src/App.js +557 -0
  102. package/example/tsconfig.json +5 -0
  103. package/example/yarn.lock +7379 -0
  104. package/ios/ReactNativeTracker-Bridging-Header.h +2 -0
  105. package/ios/ReactNativeTracker.mm +165 -0
  106. package/ios/ReactNativeTracker.swift +757 -0
  107. package/ios/{RNSnowplowTracker.xcodeproj → ReactNativeTracker.xcodeproj}/project.pbxproj +55 -79
  108. package/ios/Util/ConfigUtils.swift +206 -0
  109. package/ios/Util/TrackerVersion.swift +3 -0
  110. package/ios/Util/Utilities.swift +37 -0
  111. package/lefthook.yml +11 -0
  112. package/lib/commonjs/api.js +475 -0
  113. package/lib/commonjs/api.js.map +1 -0
  114. package/lib/commonjs/configurations.js +209 -0
  115. package/lib/commonjs/configurations.js.map +1 -0
  116. package/lib/commonjs/constants.js +85 -0
  117. package/lib/commonjs/constants.js.map +1 -0
  118. package/lib/commonjs/events.js +256 -0
  119. package/lib/commonjs/events.js.map +1 -0
  120. package/lib/commonjs/index.js +141 -0
  121. package/lib/commonjs/index.js.map +1 -0
  122. package/lib/commonjs/jsCore.js +393 -0
  123. package/lib/commonjs/jsCore.js.map +1 -0
  124. package/lib/commonjs/native.js +29 -0
  125. package/lib/commonjs/native.js.map +1 -0
  126. package/lib/commonjs/subject.js +248 -0
  127. package/lib/commonjs/subject.js.map +1 -0
  128. package/lib/commonjs/tracker.js +221 -0
  129. package/lib/commonjs/tracker.js.map +1 -0
  130. package/lib/commonjs/types.js +2 -0
  131. package/lib/commonjs/types.js.map +1 -0
  132. package/lib/commonjs/utils.js +85 -0
  133. package/lib/commonjs/utils.js.map +1 -0
  134. package/lib/commonjs/webViewInterface.js +79 -0
  135. package/lib/commonjs/webViewInterface.js.map +1 -0
  136. package/lib/module/api.js +439 -0
  137. package/lib/module/api.js.map +1 -0
  138. package/lib/module/configurations.js +197 -0
  139. package/lib/module/configurations.js.map +1 -0
  140. package/lib/module/constants.js +80 -0
  141. package/lib/module/constants.js.map +1 -0
  142. package/lib/module/events.js +240 -0
  143. package/lib/module/events.js.map +1 -0
  144. package/lib/module/index.js +129 -0
  145. package/lib/module/index.js.map +1 -0
  146. package/lib/module/jsCore.js +390 -0
  147. package/lib/module/jsCore.js.map +1 -0
  148. package/lib/module/native.js +25 -0
  149. package/lib/module/native.js.map +1 -0
  150. package/lib/module/subject.js +235 -0
  151. package/lib/module/subject.js.map +1 -0
  152. package/lib/module/tracker.js +209 -0
  153. package/lib/module/tracker.js.map +1 -0
  154. package/lib/module/types.js +2 -0
  155. package/lib/module/types.js.map +1 -0
  156. package/lib/module/utils.js +79 -0
  157. package/lib/module/utils.js.map +1 -0
  158. package/lib/module/webViewInterface.js +75 -0
  159. package/lib/module/webViewInterface.js.map +1 -0
  160. package/lib/typescript/__tests__/api.test.d.ts +2 -0
  161. package/lib/typescript/__tests__/api.test.d.ts.map +1 -0
  162. package/lib/typescript/__tests__/configurations.test.d.ts +2 -0
  163. package/lib/typescript/__tests__/configurations.test.d.ts.map +1 -0
  164. package/lib/typescript/__tests__/events.test.d.ts +2 -0
  165. package/lib/typescript/__tests__/events.test.d.ts.map +1 -0
  166. package/lib/typescript/__tests__/index.test.d.ts +2 -0
  167. package/lib/typescript/__tests__/index.test.d.ts.map +1 -0
  168. package/lib/typescript/__tests__/jsCore.test.d.ts +2 -0
  169. package/lib/typescript/__tests__/jsCore.test.d.ts.map +1 -0
  170. package/lib/typescript/__tests__/utils.test.d.ts +2 -0
  171. package/lib/typescript/__tests__/utils.test.d.ts.map +1 -0
  172. package/lib/typescript/api.d.ts +226 -0
  173. package/lib/typescript/api.d.ts.map +1 -0
  174. package/lib/typescript/configurations.d.ts +73 -0
  175. package/lib/typescript/configurations.d.ts.map +1 -0
  176. package/lib/typescript/constants.d.ts +59 -0
  177. package/lib/typescript/constants.d.ts.map +1 -0
  178. package/lib/typescript/events.d.ts +101 -0
  179. package/lib/typescript/events.d.ts.map +1 -0
  180. package/lib/typescript/index.d.ts +27 -0
  181. package/lib/typescript/index.d.ts.map +1 -0
  182. package/lib/typescript/jsCore.d.ts +140 -0
  183. package/lib/typescript/jsCore.d.ts.map +1 -0
  184. package/lib/typescript/native.d.ts +4 -0
  185. package/lib/typescript/native.d.ts.map +1 -0
  186. package/lib/typescript/subject.d.ts +91 -0
  187. package/lib/typescript/subject.d.ts.map +1 -0
  188. package/lib/typescript/tracker.d.ts +93 -0
  189. package/lib/typescript/tracker.d.ts.map +1 -0
  190. package/{dist/index.d.ts → lib/typescript/types.d.ts} +188 -75
  191. package/lib/typescript/types.d.ts.map +1 -0
  192. package/lib/typescript/utils.d.ts +35 -0
  193. package/lib/typescript/utils.d.ts.map +1 -0
  194. package/lib/typescript/webViewInterface.d.ts +15 -0
  195. package/lib/typescript/webViewInterface.d.ts.map +1 -0
  196. package/package.json +134 -52
  197. package/scripts/bootstrap.js +29 -0
  198. package/snowplow-react-native-tracker.podspec +42 -0
  199. package/src/__mocks__/react-native.js +7 -0
  200. package/src/__tests__/api.test.ts +34 -0
  201. package/src/__tests__/configurations.test.ts +620 -0
  202. package/src/__tests__/events.test.ts +749 -0
  203. package/src/__tests__/index.test.ts +27 -0
  204. package/src/__tests__/jsCore.test.ts +169 -0
  205. package/src/__tests__/utils.test.ts +23 -0
  206. package/src/api.ts +535 -0
  207. package/src/configurations.ts +337 -0
  208. package/src/constants.ts +102 -0
  209. package/src/events.ts +330 -0
  210. package/src/index.ts +189 -0
  211. package/src/jsCore.ts +553 -0
  212. package/src/native.ts +34 -0
  213. package/src/subject.ts +315 -0
  214. package/src/tracker.ts +330 -0
  215. package/src/types.ts +1087 -0
  216. package/src/utils.ts +78 -0
  217. package/src/webViewInterface.ts +105 -0
  218. package/tsconfig.build.json +5 -0
  219. package/tsconfig.json +28 -0
  220. package/turbo.json +34 -0
  221. package/yarn.lock +9333 -0
  222. package/RNSnowplowTracker.podspec +0 -24
  223. package/android/src/main/java/com/snowplowanalytics/react/tracker/RNSnowplowTrackerModule.java +0 -750
  224. package/android/src/main/java/com/snowplowanalytics/react/tracker/RNSnowplowTrackerPackage.java +0 -29
  225. package/android/src/main/java/com/snowplowanalytics/react/util/ConfigUtil.java +0 -351
  226. package/android/src/main/java/com/snowplowanalytics/react/util/EventUtil.java +0 -339
  227. package/android/src/main/java/com/snowplowanalytics/react/util/TrackerVersion.java +0 -7
  228. package/dist/index.js +0 -2026
  229. package/dist/index.js.map +0 -1
  230. package/ios/RNSnowplowTracker.h +0 -34
  231. package/ios/RNSnowplowTracker.m +0 -911
  232. package/ios/Util/NSDictionary+RNSP_TypeMethods.h +0 -33
  233. package/ios/Util/NSDictionary+RNSP_TypeMethods.m +0 -40
  234. package/ios/Util/RNConfigUtils.h +0 -44
  235. package/ios/Util/RNConfigUtils.m +0 -209
  236. package/ios/Util/RNTrackerVersion.h +0 -27
  237. package/ios/Util/RNTrackerVersion.m +0 -27
  238. package/ios/Util/RNUtilities.h +0 -32
  239. package/ios/Util/RNUtilities.m +0 -68
@@ -0,0 +1,757 @@
1
+ import SnowplowTracker
2
+
3
+ @objc(ReactNativeTracker)
4
+ class ReactNativeTracker: NSObject {
5
+
6
+ @objc(createTracker:resolver:rejecter:)
7
+ func createTracker(argmap:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
8
+
9
+ let trackerNs = argmap.object(forKey: "namespace") as! String
10
+ let networkConfig = argmap.object(forKey: "networkConfig") as! NSDictionary
11
+
12
+ // NetworkConfiguration
13
+ let method = networkConfig.object(forKey: "method") as? String
14
+ let httpMethod: HttpMethodOptions = method == "get" ? .get : .post
15
+ let endpoint = networkConfig.object(forKey: "endpoint") as! String
16
+ let networkConfiguration = NetworkConfiguration(endpoint: endpoint, method: httpMethod)
17
+ if let customPostPath = networkConfig.object(forKey: "customPostPath") as? String {
18
+ networkConfiguration.customPostPath = customPostPath
19
+ }
20
+ if let requestHeaders = networkConfig.object(forKey: "requestHeaders") as? Dictionary<String, String> {
21
+ networkConfiguration.requestHeaders = requestHeaders
22
+ }
23
+
24
+ // Configurations
25
+ var controllers: [ConfigurationProtocol] = []
26
+
27
+ // TrackerConfiguration
28
+ let trackerConfiguration = ConfigUtils.mkTrackerConfig(argmap.object(forKey: "trackerConfig") as? NSDictionary ?? NSDictionary())
29
+ controllers.append(trackerConfiguration)
30
+
31
+ // SessionConfiguration
32
+ if let sessionArg = argmap.object(forKey: "sessionConfig") as? NSDictionary,
33
+ let sessionConfiguration = ConfigUtils.mkSessionConfig(sessionArg) {
34
+ controllers.append(sessionConfiguration)
35
+ }
36
+
37
+ // EmitterConfiguration
38
+ if let emitterArg = argmap.object(forKey: "emitterConfig") as? NSDictionary,
39
+ let emitterConfiguration = ConfigUtils.mkEmitterConfig(emitterArg) {
40
+ controllers.append(emitterConfiguration)
41
+ }
42
+
43
+ // SubjectConfiguration
44
+ if let subjectArg = argmap.object(forKey: "subjectConfig") as? NSDictionary,
45
+ let subjectConfiguration = ConfigUtils.mkSubjectConfig(subjectArg) {
46
+ controllers.append(subjectConfiguration)
47
+ }
48
+
49
+ // GdprConfiguration
50
+ if let gdprArg = argmap.object(forKey: "gdprConfig") as? NSDictionary,
51
+ let gdprConfiguration = ConfigUtils.mkGdprConfig(gdprArg) {
52
+ controllers.append(gdprConfiguration)
53
+ }
54
+
55
+ // GConfiguration
56
+ if let gcArg = argmap.object(forKey: "gcConfig") as? NSArray,
57
+ let gcConfiguration = ConfigUtils.mkGCConfig(gcArg) {
58
+ controllers.append(gcConfiguration)
59
+ }
60
+
61
+ if let tracker = Snowplow.createTracker(namespace: trackerNs, network: networkConfiguration, configurations: controllers) {
62
+ resolve(true)
63
+ } else {
64
+ let error = NSError(domain: "SnowplowTracker", code: 200)
65
+ reject("ERROR", "tracker intialization failed", error)
66
+ }
67
+ }
68
+
69
+ @objc(removeTracker:resolver:rejecter:)
70
+ func removeTracker(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
71
+ let namespace = details.object(forKey: "tracker") as? String
72
+ let trackerController = trackerByNamespace(namespace)
73
+ let removed = Snowplow.remove(tracker: trackerController)
74
+ resolve(removed);
75
+ }
76
+
77
+ @objc(removeAllTrackers:rejecter:)
78
+ func removeAllTrackers(resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
79
+ Snowplow.removeAllTrackers()
80
+ resolve(true)
81
+ }
82
+
83
+ @objc(trackSelfDescribingEvent:resolver:rejecter:)
84
+ func trackSelfDescribingEvent(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
85
+
86
+ let namespace = details.object(forKey: "tracker") as? String
87
+ if let trackerController = trackerByNamespace(namespace),
88
+ let argmap = details.object(forKey: "eventData") as? NSDictionary,
89
+ let schema = argmap.object(forKey: "schema") as? String,
90
+ let data = argmap.object(forKey: "data") as? Dictionary<String, Any> {
91
+
92
+ let eventData = SelfDescribingJson(
93
+ schema: schema,
94
+ andDictionary: data
95
+ )
96
+
97
+ let event = SelfDescribing(eventData: eventData)
98
+ if let contexts = details.object(forKey: "contexts") as? NSArray {
99
+ event.entities = Utilities.mkSDJArray(contexts)
100
+ }
101
+
102
+ _ = trackerController.track(event)
103
+ resolve(true);
104
+ } else {
105
+ let error = NSError(domain: "SnowplowTracker", code: 200)
106
+ reject("ERROR", "tracker with given namespace not found", error);
107
+ }
108
+ }
109
+
110
+ @objc(trackStructuredEvent:resolver:rejecter:)
111
+ func trackStructuredEvent(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
112
+
113
+ let namespace = details.object(forKey: "tracker") as? String
114
+ if let trackerController = trackerByNamespace(namespace),
115
+ let argmap = details.object(forKey: "eventData") as? NSDictionary,
116
+ let category = argmap.object(forKey: "category") as? String,
117
+ let action = argmap.object(forKey: "action") as? String {
118
+ let event = Structured(category: category, action: action)
119
+
120
+ if let label = argmap.object(forKey: "label") as? String {
121
+ event.label = label
122
+ }
123
+ if let property = argmap.object(forKey: "property") as? String {
124
+ event.property = property
125
+ }
126
+ if let value = argmap.object(forKey: "value") as? NSNumber {
127
+ event.value = value
128
+ }
129
+
130
+ if let contexts = details.object(forKey: "contexts") as? NSArray {
131
+ event.entities = Utilities.mkSDJArray(contexts)
132
+ }
133
+ _ = trackerController.track(event)
134
+ resolve(true)
135
+ } else {
136
+ let error = NSError(domain: "SnowplowTracker", code: 200)
137
+ reject("ERROR", "tracker with given namespace not found", error)
138
+ }
139
+ }
140
+
141
+ @objc(trackScreenViewEvent:resolver:rejecter:)
142
+ func trackScreenViewEvent(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
143
+
144
+ let namespace = details.object(forKey: "tracker") as? String
145
+ if let trackerController = trackerByNamespace(namespace),
146
+ let argmap = details.object(forKey: "eventData") as? NSDictionary,
147
+ let screenName = argmap.object(forKey: "name") as? String {
148
+
149
+ var screenUuid: UUID?
150
+ if let screenId = argmap.object(forKey: "id") as? String {
151
+ screenUuid = UUID(uuidString: screenId)
152
+ if screenUuid == nil {
153
+ let error = NSError(domain: "SnowplowTracker", code: 200)
154
+ reject("ERROR", "screenId has to be a valid UUID string", error)
155
+ return
156
+ }
157
+ }
158
+
159
+ let event = ScreenView(name: screenName, screenId: screenUuid)
160
+
161
+ if let type = argmap.object(forKey: "type") as? String {
162
+ event.type = type
163
+ }
164
+ if let previousName = argmap.object(forKey: "previousName") as? String {
165
+ event.previousName = previousName;
166
+ }
167
+ if let previousId = argmap.object(forKey: "previousId") as? String {
168
+ event.previousId = previousId
169
+ }
170
+ if let previousType = argmap.object(forKey: "previousType") as? String {
171
+ event.previousType = previousType
172
+ }
173
+ if let transitionType = argmap.object(forKey: "transitionType") as? String {
174
+ event.transitionType = transitionType
175
+ }
176
+
177
+ if let contexts = details.object(forKey: "contexts") as? NSArray {
178
+ event.entities = Utilities.mkSDJArray(contexts)
179
+ }
180
+ _ = trackerController.track(event)
181
+ resolve(true)
182
+ } else {
183
+ let error = NSError(domain: "SnowplowTracker", code: 200)
184
+ reject("ERROR", "tracker with given namespace not found", error)
185
+ }
186
+ }
187
+
188
+ @objc(trackPageViewEvent:resolver:rejecter:)
189
+ func trackPageViewEvent(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
190
+ let namespace = details.object(forKey: "tracker") as? String
191
+ if let trackerController = trackerByNamespace(namespace),
192
+ let argmap = details.object(forKey: "eventData") as? NSDictionary,
193
+ let pageUrl = argmap.object(forKey: "pageUrl") as? String {
194
+ let event = PageView(pageUrl: pageUrl)
195
+
196
+ if let pageTitle = argmap.object(forKey: "pageTitle") as? String {
197
+ event.pageTitle = pageTitle
198
+ }
199
+ if let referrer = argmap.object(forKey: "referrer") as? String {
200
+ event.referrer = referrer
201
+ }
202
+
203
+ if let contexts = details.object(forKey: "contexts") as? NSArray {
204
+ event.entities = Utilities.mkSDJArray(contexts)
205
+ }
206
+ _ = trackerController.track(event)
207
+ resolve(true)
208
+ } else {
209
+ let error = NSError(domain: "SnowplowTracker", code: 200)
210
+ reject("ERROR", "tracker with given namespace not found", error)
211
+ }
212
+ }
213
+
214
+ @objc(trackTimingEvent:resolver:rejecter:)
215
+ func trackTimingEvent(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
216
+ let namespace = details.object(forKey: "tracker") as? String
217
+ if let trackerController = trackerByNamespace(namespace),
218
+ let argmap = details.object(forKey: "eventData") as? NSDictionary,
219
+ let category = argmap.object(forKey: "category") as? String,
220
+ let variable = argmap.object(forKey: "variable") as? String,
221
+ let timing = argmap.object(forKey: "timing") as? NSNumber {
222
+ let event = Timing(category: category, variable: variable, timing: timing.intValue)
223
+
224
+ if let label = argmap.object(forKey: "label") as? String {
225
+ event.label = label
226
+ }
227
+
228
+ if let contexts = details.object(forKey: "contexts") as? NSArray {
229
+ event.entities = Utilities.mkSDJArray(contexts)
230
+ }
231
+ _ = trackerController.track(event)
232
+ resolve(true)
233
+ } else {
234
+ let error = NSError(domain: "SnowplowTracker", code: 200)
235
+ reject("ERROR", "tracker with given namespace not found", error)
236
+ }
237
+ }
238
+
239
+ @objc(trackConsentGrantedEvent:resolver:rejecter:)
240
+ func trackConsentGrantedEvent(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
241
+
242
+ let namespace = details.object(forKey: "tracker") as? String
243
+ if let trackerController = trackerByNamespace(namespace),
244
+ let argmap = details.object(forKey: "eventData") as? NSDictionary,
245
+ let expiry = argmap.object(forKey: "expiry") as? String,
246
+ let documentId = argmap.object(forKey: "documentId") as? String,
247
+ let version = argmap.object(forKey: "version") as? String {
248
+
249
+ let event = ConsentGranted(expiry: expiry, documentId: documentId, version: version)
250
+
251
+ if let name = argmap.object(forKey: "name") as? String {
252
+ event.name = name;
253
+ }
254
+ if let documentDescription = argmap.object(forKey: "documentDescription") as? String {
255
+ event.documentDescription = documentDescription;
256
+ }
257
+
258
+ if let contexts = details.object(forKey: "contexts") as? NSArray {
259
+ event.entities = Utilities.mkSDJArray(contexts)
260
+ }
261
+ _ = trackerController.track(event)
262
+ resolve(true)
263
+ } else {
264
+ let error = NSError(domain: "SnowplowTracker", code: 200)
265
+ reject("ERROR", "tracker with given namespace not found", error)
266
+ }
267
+ }
268
+
269
+ @objc(trackConsentWithdrawnEvent:resolver:rejecter:)
270
+ func trackConsentWithdrawnEvent(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
271
+
272
+ let namespace = details.object(forKey: "tracker") as? String
273
+ if let trackerController = trackerByNamespace(namespace),
274
+ let argmap = details.object(forKey: "eventData") as? NSDictionary {
275
+
276
+ let event = ConsentWithdrawn()
277
+
278
+ if let all = argmap.object(forKey: "all") as? NSNumber {
279
+ event.all = all.boolValue
280
+ }
281
+ if let documentId = argmap.object(forKey: "documentId") as? String {
282
+ event.documentId = documentId
283
+ }
284
+ if let version = argmap.object(forKey: "version") as? String {
285
+ event.version = version
286
+ }
287
+ if let name = argmap.object(forKey: "name") as? String {
288
+ event.name = name
289
+ }
290
+ if let documentDescription = argmap.object(forKey: "documentDescription") as? String {
291
+ event.documentDescription = documentDescription
292
+ }
293
+
294
+ if let contexts = details.object(forKey: "contexts") as? NSArray {
295
+ event.entities = Utilities.mkSDJArray(contexts)
296
+ }
297
+ _ = trackerController.track(event)
298
+ resolve(true)
299
+ } else {
300
+ let error = NSError(domain: "SnowplowTracker", code: 200)
301
+ reject("ERROR", "tracker with given namespace not found", error)
302
+ }
303
+ }
304
+
305
+ @objc(trackEcommerceTransactionEvent:resolver:rejecter:)
306
+ func trackEcommerceTransactionEvent(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
307
+ let namespace = details.object(forKey: "tracker") as? String
308
+ if let trackerController = trackerByNamespace(namespace),
309
+ let argmap = details.object(forKey: "eventData") as? NSDictionary,
310
+ let orderId = argmap.object(forKey: "orderId") as? String,
311
+ let totalValue = argmap.object(forKey: "totalValue") as? NSNumber {
312
+ var transItems: [EcommerceItem] = []
313
+ if let items = argmap.object(forKey: "items") as? NSArray {
314
+ for item in items {
315
+ if let item = item as? NSDictionary,
316
+ let sku = item.object(forKey: "sku") as? String,
317
+ let price = item.object(forKey: "price") as? NSNumber,
318
+ let quantity = item.object(forKey: "quantity") as? NSNumber {
319
+ let ecomItem = EcommerceItem(sku: sku, price: price.doubleValue, quantity: quantity.intValue)
320
+ if let name = argmap.object(forKey: "name") as? String {
321
+ ecomItem.name = name
322
+ }
323
+ if let category = argmap.object(forKey: "category") as? String {
324
+ ecomItem.category = category
325
+ }
326
+ if let currency = argmap.object(forKey: "currency") as? String {
327
+ ecomItem.currency = currency;
328
+ }
329
+
330
+ transItems.append(ecomItem)
331
+ }
332
+ }
333
+ }
334
+
335
+ let event = Ecommerce(orderId: orderId, totalValue: totalValue.doubleValue, items: transItems)
336
+
337
+ if let contexts = details.object(forKey: "contexts") as? NSArray {
338
+ event.entities = Utilities.mkSDJArray(contexts)
339
+ }
340
+ _ = trackerController.track(event)
341
+ resolve(true)
342
+ } else {
343
+ let error = NSError(domain: "SnowplowTracker", code: 200)
344
+ reject("ERROR", "tracker with given namespace not found", error)
345
+ }
346
+ }
347
+
348
+ @objc(trackDeepLinkReceivedEvent:resolver:rejecter:)
349
+ func trackDeepLinkReceivedEvent(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
350
+
351
+ let namespace = details.object(forKey: "tracker") as? String
352
+ if let trackerController = trackerByNamespace(namespace),
353
+ let argmap = details.object(forKey: "eventData") as? NSDictionary,
354
+ let url = argmap.object(forKey: "url") as? String {
355
+ let event = DeepLinkReceived(url: url)
356
+
357
+ if let referrer = argmap.object(forKey: "referrer") as? String {
358
+ event.referrer = referrer
359
+ }
360
+
361
+ if let contexts = details.object(forKey: "contexts") as? NSArray {
362
+ event.entities = Utilities.mkSDJArray(contexts)
363
+ }
364
+ _ = trackerController.track(event)
365
+ resolve(true)
366
+ } else {
367
+ let error = NSError(domain: "SnowplowTracker", code: 200)
368
+ reject("ERROR", "tracker with given namespace not found", error)
369
+ }
370
+ }
371
+
372
+ @objc(trackMessageNotificationEvent:resolver:rejecter:)
373
+ func trackMessageNotificationEvent(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
374
+
375
+ let namespace = details.object(forKey: "tracker") as? String
376
+ if let trackerController = trackerByNamespace(namespace),
377
+ let argmap = details.object(forKey: "eventData") as? NSDictionary,
378
+ let title = argmap.object(forKey: "title") as? String,
379
+ let body = argmap.object(forKey: "body") as? String {
380
+ let triggerStr = argmap.object(forKey: "trigger") as? String
381
+ var trigger: MessageNotificationTrigger = .other
382
+
383
+ if triggerStr == "push" {
384
+ trigger = .push
385
+ } else if triggerStr == "location" {
386
+ trigger = .location
387
+ } else if triggerStr == "calendar" {
388
+ trigger = .calendar
389
+ } else if triggerStr == "timeInterval" {
390
+ trigger = .timeInterval
391
+ }
392
+ let event = MessageNotification(title: title, body: body, trigger: trigger)
393
+
394
+ if let action = argmap.object(forKey: "action") as? String {
395
+ event.action = action
396
+ }
397
+ if let attachmentsMap = argmap.object(forKey: "attachments") as? NSArray {
398
+ var attachments: [MessageNotificationAttachment] = []
399
+ for attachmentMap in attachmentsMap {
400
+ if let attachmentMap = attachmentMap as? NSDictionary,
401
+ let identifier = attachmentMap.object(forKey: "identifier") as? String,
402
+ let type = attachmentMap.object(forKey: "type") as? String,
403
+ let url = attachmentMap.object(forKey: "url") as? String {
404
+ let attachment = MessageNotificationAttachment(identifier: identifier, type: type, url: url)
405
+ attachments.append(attachment)
406
+ }
407
+ }
408
+
409
+ event.attachments = attachments
410
+ }
411
+ if let bodyLocArgs = argmap.object(forKey: "bodyLocArgs") as? NSArray {
412
+ event.bodyLocArgs = bodyLocArgs.map { $0 as? String}.compactMap { $0 }
413
+ }
414
+ if let bodyLocKey = argmap.object(forKey: "bodyLocKey") as? String {
415
+ event.bodyLocKey = bodyLocKey
416
+ }
417
+ if let category = argmap.object(forKey: "category") as? String {
418
+ event.category = category
419
+ }
420
+ if let contentAvailable = argmap.object(forKey: "contentAvailable") as? NSNumber {
421
+ event.contentAvailable = contentAvailable.boolValue
422
+ }
423
+ if let group = argmap.object(forKey: "group") as? String {
424
+ event.group = group
425
+ }
426
+ if let icon = argmap.object(forKey: "icon") as? String {
427
+ event.icon = icon
428
+ }
429
+ if let notificationCount = argmap.object(forKey: "notificationCount") as? NSNumber {
430
+ event.notificationCount = notificationCount.intValue
431
+ }
432
+ if let notificationTimestamp = argmap.object(forKey: "notificationTimestamp") as? String {
433
+ event.notificationTimestamp = notificationTimestamp
434
+ }
435
+ if let sound = argmap.object(forKey: "sound") as? String {
436
+ event.sound = sound
437
+ }
438
+ if let subtitle = argmap.object(forKey: "subtitle") as? String {
439
+ event.subtitle = subtitle
440
+ }
441
+ if let tag = argmap.object(forKey: "tag") as? String {
442
+ event.tag = tag
443
+ }
444
+ if let threadIdentifier = argmap.object(forKey: "threadIdentifier") as? String {
445
+ event.threadIdentifier = threadIdentifier
446
+ }
447
+ if let titleLocArgs = argmap.object(forKey: "titleLocArgs") as? NSArray {
448
+ event.titleLocArgs = titleLocArgs.map { $0 as? String}.compactMap { $0 }
449
+ }
450
+ if let titleLocKey = argmap.object(forKey: "titleLocKey") as? String {
451
+ event.titleLocKey = titleLocKey
452
+ }
453
+
454
+ if let contexts = details.object(forKey: "contexts") as? NSArray {
455
+ event.entities = Utilities.mkSDJArray(contexts)
456
+ }
457
+ _ = trackerController.track(event)
458
+ resolve(true)
459
+ } else {
460
+ let error = NSError(domain: "SnowplowTracker", code: 200)
461
+ reject("ERROR", "tracker with given namespace not found", error)
462
+ }
463
+ }
464
+
465
+ @objc(removeGlobalContexts:resolver:rejecter:)
466
+ func removeGlobalContexts(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
467
+ let namespace = details.object(forKey: "tracker") as? String
468
+ if let trackerController = trackerByNamespace(namespace),
469
+ let tag = details.object(forKey: "removeTag") as? String {
470
+ _ = trackerController.globalContexts?.remove(tag: tag)
471
+ resolve(true)
472
+ } else {
473
+ let error = NSError(domain: "SnowplowTracker", code: 200)
474
+ reject("ERROR", "tracker with given namespace not found", error)
475
+ }
476
+ }
477
+
478
+ @objc(addGlobalContexts:resolver:rejecter:)
479
+ func addGlobalContexts(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
480
+ let namespace = details.object(forKey: "tracker") as? String
481
+ if let trackerController = trackerByNamespace(namespace),
482
+ let gcArg = details.object(forKey: "addGlobalContext") as? NSDictionary,
483
+ let tag = gcArg.object(forKey: "tag") as? String,
484
+ let globalContexts = gcArg.object(forKey: "globalContexts") as? NSArray {
485
+ let staticContexts = Utilities.mkSDJArray(globalContexts)
486
+ let gcStatic = GlobalContext(staticContexts: staticContexts)
487
+
488
+ _ = trackerController.globalContexts?.add(tag: tag, contextGenerator: gcStatic)
489
+
490
+ resolve(true)
491
+ } else {
492
+ let error = NSError(domain: "SnowplowTracker", code: 200)
493
+ reject("ERROR", "tracker with given namespace not found", error)
494
+ }
495
+ }
496
+
497
+ @objc(setUserId:resolver:rejecter:)
498
+ func setUserId(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
499
+ let namespace = details.object(forKey: "tracker") as? String
500
+ if let trackerController = trackerByNamespace(namespace) {
501
+ let newUid = details.object(forKey: "userId") as? String
502
+ trackerController.subject?.userId = newUid
503
+
504
+ resolve(true)
505
+ } else {
506
+ let error = NSError(domain: "SnowplowTracker", code: 200)
507
+ reject("ERROR", "tracker with given namespace not found", error)
508
+ }
509
+ }
510
+
511
+ @objc(setNetworkUserId:resolver:rejecter:)
512
+ func setNetworkUserId(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
513
+ let namespace = details.object(forKey: "tracker") as? String
514
+ if let trackerController = trackerByNamespace(namespace) {
515
+
516
+ let newNuid = details.object(forKey: "networkUserId") as? String
517
+ trackerController.subject?.networkUserId = newNuid
518
+
519
+ resolve(true)
520
+ } else {
521
+ let error = NSError(domain: "SnowplowTracker", code: 200)
522
+ reject("ERROR", "tracker with given namespace not found", error)
523
+ }
524
+ }
525
+
526
+ @objc(setDomainUserId:resolver:rejecter:)
527
+ func setDomainUserId(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
528
+ let namespace = details.object(forKey: "tracker") as? String
529
+ if let trackerController = trackerByNamespace(namespace) {
530
+
531
+ let newDuid = details.object(forKey: "domainUserId") as? String
532
+ trackerController.subject?.domainUserId = newDuid
533
+
534
+ resolve(true)
535
+ } else {
536
+ let error = NSError(domain: "SnowplowTracker", code: 200)
537
+ reject("ERROR", "tracker with given namespace not found", error)
538
+ }
539
+ }
540
+
541
+ @objc(setIpAddress:resolver:rejecter:)
542
+ func setIpAddress(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
543
+ let namespace = details.object(forKey: "tracker") as? String
544
+ if let trackerController = trackerByNamespace(namespace) {
545
+
546
+ let newIp = details.object(forKey: "ipAddress") as? String
547
+ trackerController.subject?.ipAddress = newIp
548
+
549
+ resolve(true)
550
+ } else {
551
+ let error = NSError(domain: "SnowplowTracker", code: 200)
552
+ reject("ERROR", "tracker with given namespace not found", error)
553
+ }
554
+ }
555
+
556
+ @objc(setUseragent:resolver:rejecter:)
557
+ func setUseragent(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
558
+ let namespace = details.object(forKey: "tracker") as? String
559
+ if let trackerController = trackerByNamespace(namespace) {
560
+
561
+ let newUagent = details.object(forKey: "useragent") as? String
562
+ trackerController.subject?.useragent = newUagent
563
+
564
+ resolve(true)
565
+ } else {
566
+ let error = NSError(domain: "SnowplowTracker", code: 200)
567
+ reject("ERROR", "tracker with given namespace not found", error)
568
+ }
569
+ }
570
+
571
+ @objc(setTimezone:resolver:rejecter:)
572
+ func setTimezone(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
573
+ let namespace = details.object(forKey: "tracker") as? String
574
+ if let trackerController = trackerByNamespace(namespace) {
575
+
576
+ let newTz = details.object(forKey: "timezone") as? String
577
+ trackerController.subject?.timezone = newTz
578
+
579
+ resolve(true)
580
+ } else {
581
+ let error = NSError(domain: "SnowplowTracker", code: 200)
582
+ reject("ERROR", "tracker with given namespace not found", error)
583
+ }
584
+ }
585
+
586
+ @objc(setLanguage:resolver:rejecter:)
587
+ func setLanguage(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
588
+ let namespace = details.object(forKey: "tracker") as? String
589
+ if let trackerController = trackerByNamespace(namespace) {
590
+
591
+ let newLang = details.object(forKey: "language") as? String
592
+ trackerController.subject?.language = newLang
593
+
594
+ resolve(true)
595
+ } else {
596
+ let error = NSError(domain: "SnowplowTracker", code: 200)
597
+ reject("ERROR", "tracker with given namespace not found", error)
598
+ }
599
+ }
600
+
601
+ @objc(setScreenResolution:resolver:rejecter:)
602
+ func setScreenResolution(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
603
+ let namespace = details.object(forKey: "tracker") as? String
604
+ if let trackerController = trackerByNamespace(namespace) {
605
+
606
+ if let newRes = details.object(forKey: "screenResolution") as? NSArray,
607
+ let resWidth = newRes.object(at: 0) as? NSNumber,
608
+ let resHeight = newRes.object(at: 1) as? NSNumber {
609
+ let resSize = SPSize(width: resWidth.intValue, height: resHeight.intValue)
610
+ trackerController.subject?.screenResolution = resSize
611
+ }
612
+ else {
613
+ trackerController.subject?.screenResolution = nil
614
+ }
615
+
616
+ resolve(true)
617
+ } else {
618
+ let error = NSError(domain: "SnowplowTracker", code: 200)
619
+ reject("ERROR", "tracker with given namespace not found", error)
620
+ }
621
+ }
622
+
623
+ @objc(setScreenViewport:resolver:rejecter:)
624
+ func setScreenViewport(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
625
+ let namespace = details.object(forKey: "tracker") as? String
626
+ if let trackerController = trackerByNamespace(namespace) {
627
+
628
+ if let newView = details.object(forKey: "screenViewport") as? NSArray,
629
+ let vpWidth = newView.object(at: 0) as? NSNumber,
630
+ let vpHeight = newView.object(at: 1) as? NSNumber {
631
+ let vpSize = SPSize(width: vpWidth.intValue, height: vpHeight.intValue)
632
+ trackerController.subject?.screenViewPort = vpSize
633
+ }
634
+ else {
635
+ trackerController.subject?.screenViewPort = nil
636
+ }
637
+
638
+ resolve(true)
639
+ } else {
640
+ let error = NSError(domain: "SnowplowTracker", code: 200)
641
+ reject("ERROR", "tracker with given namespace not found", error)
642
+ }
643
+ }
644
+
645
+ @objc(setColorDepth:resolver:rejecter:)
646
+ func setColorDepth(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
647
+ let namespace = details.object(forKey: "tracker") as? String
648
+ if let trackerController = trackerByNamespace(namespace) {
649
+
650
+ let newColorD = details.object(forKey: "colorDepth") as? NSNumber
651
+ trackerController.subject?.colorDepth = newColorD
652
+
653
+ resolve(true)
654
+ } else {
655
+ let error = NSError(domain: "SnowplowTracker", code: 200)
656
+ reject("ERROR", "tracker with given namespace not found", error)
657
+ }
658
+ }
659
+
660
+ @objc(getSessionUserId:resolver:rejecter:)
661
+ func getSessionUserId(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
662
+ let namespace = details.object(forKey: "tracker") as? String
663
+ if let trackerController = trackerByNamespace(namespace) {
664
+
665
+ resolve(trackerController.session?.userId)
666
+
667
+ } else {
668
+ let error = NSError(domain: "SnowplowTracker", code: 200)
669
+ reject("ERROR", "tracker with given namespace not found", error)
670
+ }
671
+ }
672
+
673
+ @objc(getSessionId:resolver:rejecter:)
674
+ func getSessionId(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
675
+ let namespace = details.object(forKey: "tracker") as? String
676
+ if let trackerController = trackerByNamespace(namespace) {
677
+
678
+ resolve(trackerController.session?.sessionId)
679
+
680
+ } else {
681
+ let error = NSError(domain: "SnowplowTracker", code: 200)
682
+ reject("ERROR", "tracker with given namespace not found", error)
683
+ }
684
+ }
685
+
686
+ @objc(getSessionIndex:resolver:rejecter:)
687
+ func getSessionIndex(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
688
+ let namespace = details.object(forKey: "tracker") as? String
689
+ if let trackerController = trackerByNamespace(namespace) {
690
+
691
+ if let sessionIndex = trackerController.session?.sessionIndex {
692
+ resolve(NSNumber(integerLiteral: sessionIndex))
693
+ } else {
694
+ resolve(nil)
695
+ }
696
+ } else {
697
+ let error = NSError(domain: "SnowplowTracker", code: 200)
698
+ reject("ERROR", "tracker with given namespace not found", error)
699
+ }
700
+ }
701
+
702
+ @objc(getIsInBackground:resolver:rejecter:)
703
+ func getIsInBackground(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
704
+ let namespace = details.object(forKey: "tracker") as? String
705
+ if let trackerController = trackerByNamespace(namespace) {
706
+
707
+ if let isInBg = trackerController.session?.isInBackground {
708
+ resolve(NSNumber(booleanLiteral: isInBg))
709
+ } else {
710
+ resolve(nil)
711
+ }
712
+ } else {
713
+ let error = NSError(domain: "SnowplowTracker", code: 200)
714
+ reject("ERROR", "tracker with given namespace not found", error)
715
+ }
716
+ }
717
+
718
+ @objc(getBackgroundIndex:resolver:rejecter:)
719
+ func getBackgroundIndex(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
720
+ let namespace = details.object(forKey: "tracker") as? String
721
+ if let trackerController = trackerByNamespace(namespace) {
722
+
723
+ if let bgIdx = trackerController.session?.backgroundIndex {
724
+ resolve(NSNumber(integerLiteral: bgIdx))
725
+ } else {
726
+ resolve(nil)
727
+ }
728
+ } else {
729
+ let error = NSError(domain: "SnowplowTracker", code: 200)
730
+ reject("ERROR", "tracker with given namespace not found", error)
731
+ }
732
+ }
733
+
734
+ @objc(getForegroundIndex:resolver:rejecter:)
735
+ func getForegroundIndex(details:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
736
+ let namespace = details.object(forKey: "tracker") as? String
737
+ if let trackerController = trackerByNamespace(namespace) {
738
+
739
+ if let fgIdx = trackerController.session?.foregroundIndex {
740
+ resolve(NSNumber(integerLiteral: fgIdx))
741
+ } else {
742
+ resolve(nil)
743
+ }
744
+ } else {
745
+ let error = NSError(domain: "SnowplowTracker", code: 200)
746
+ reject("ERROR", "tracker with given namespace not found", error)
747
+ }
748
+ }
749
+
750
+ func trackerByNamespace(_ namespace: String?) -> TrackerController? {
751
+ if let namespace = namespace {
752
+ return Snowplow.tracker(namespace: namespace)
753
+ } else {
754
+ return Snowplow.defaultTracker()
755
+ }
756
+ }
757
+ }