@dashx/react-native 1.1.5 → 1.3.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.
@@ -1,231 +0,0 @@
1
- package com.dashx.rn.sdk
2
-
3
- import com.dashx.rn.sdk.util.*
4
- import com.dashx.android.DashX
5
- import com.dashx.android.DashXLog
6
- import com.dashx.android.DashXLog.LogLevel
7
- import com.facebook.react.bridge.*
8
- import kotlinx.serialization.decodeFromString
9
- import kotlinx.serialization.encodeToString
10
- import kotlinx.serialization.json.Json
11
- import kotlinx.serialization.json.JsonObject
12
-
13
- class DashXReactNativeModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
14
- private val tag = DashXReactNativeModule::class.java.simpleName
15
-
16
- override fun initialize() {
17
- super.initialize()
18
- MessageReceivedEventHolder.reactContext = reactContext
19
- }
20
-
21
- override fun invalidate() {
22
- MessageReceivedEventHolder.reactContext = null
23
- super.invalidate()
24
- }
25
-
26
- override fun getName(): String {
27
- return "DashXReactNative"
28
- }
29
-
30
- @ReactMethod
31
- fun setLogLevel(level: Int) {
32
- val logLevel = LogLevel.values().firstOrNull { it.code == level } ?: LogLevel.OFF
33
- DashXLog.setLogLevel(logLevel)
34
- }
35
-
36
- @ReactMethod
37
- fun configure(options: ReadableMap) {
38
- DashX.configure(
39
- reactContext,
40
- options.getString("publicKey")!!,
41
- options.getStringIfPresent("baseURI"),
42
- options.getStringIfPresent("targetEnvironment")
43
- )
44
- }
45
-
46
- @ReactMethod
47
- fun identify(options: ReadableMap?) {
48
- val optionsHashMap = options?.toHashMap()
49
- ?.filterValues { it != null }
50
- ?.mapValues { it.value.toString() }
51
- DashX.identify(optionsHashMap?.let { HashMap(it) })
52
- }
53
-
54
- @ReactMethod
55
- fun setIdentity(uid: String?, token: String?) {
56
- DashX.setIdentity(uid, token)
57
- }
58
-
59
- @ReactMethod
60
- fun reset() {
61
- DashX.reset()
62
- }
63
-
64
- @ReactMethod
65
- fun track(event: String, data: ReadableMap?) {
66
- val jsonData = try {
67
- data?.toHashMap()
68
- ?.filterValues { it != null }
69
- ?.mapValues { it.value.toString() }
70
- ?.let { HashMap(it) }
71
- } catch (e: Exception) {
72
- DashXLog.d(tag, e.message)
73
- return
74
- }
75
-
76
- DashX.track(event, jsonData)
77
- }
78
-
79
- @ReactMethod
80
- fun screen(screenName: String, data: ReadableMap?) {
81
- val screenData = data?.toHashMap()
82
- ?.filterValues { it != null }
83
- ?.mapValues { it.value.toString() }
84
- ?.let { HashMap(it) }
85
- ?: HashMap()
86
- DashX.screen(screenName, screenData)
87
- }
88
-
89
- @ReactMethod
90
- fun fetchRecord(urn: String, options: ReadableMap?, promise: Promise) {
91
- val preview = options?.getBooleanIfPresent("preview")
92
- val language = options?.getStringIfPresent("language")
93
- val fields = try {
94
- convertReadableArrayToKJsonList(options?.getArray("fields"))
95
- } catch (e: Exception) {
96
- DashXLog.d(tag, e.message)
97
- promise.reject("EUNSPECIFIED", "Error parsing fields: ${e.message}")
98
- return
99
- }
100
- val include = try {
101
- convertReadableArrayToKJsonList(options?.getArray("include"))
102
- } catch (e: Exception) {
103
- DashXLog.d(tag, e.message)
104
- promise.reject("EUNSPECIFIED", "Error parsing include: ${e.message}")
105
- return
106
- }
107
- val exclude = try {
108
- convertReadableArrayToKJsonList(options?.getArray("exclude"))
109
- } catch (e: Exception) {
110
- DashXLog.d(tag, e.message)
111
- promise.reject("EUNSPECIFIED", "Error parsing exclude: ${e.message}")
112
- return
113
- }
114
-
115
- DashX.fetchRecord(
116
- urn = urn,
117
- preview = preview,
118
- language = language,
119
- fields = fields,
120
- include = include,
121
- exclude = exclude,
122
- onError = {
123
- promise.reject("EUNSPECIFIED", it.message)
124
- },
125
- onSuccess = {
126
- promise.resolve(convertJsonToMap(convertKJsonToJson(it)))
127
- }
128
- )
129
- }
130
-
131
- @ReactMethod
132
- fun searchRecords(resource: String, options: ReadableMap?, promise: Promise) {
133
- val jsonFilter = try {
134
- convertMapToJson(options?.getMap("filter"))?.let { convertJsonToKJson(it) }
135
- } catch (e: Exception) {
136
- DashXLog.d(tag, e.message)
137
- promise.reject("EUNSPECIFIED", "Error parsing filter: ${e.message}")
138
- return
139
- }
140
- val order = try {
141
- convertReadableArrayToKJsonList(options?.getArray("order"))
142
- } catch (e: Exception) {
143
- DashXLog.d(tag, e.message)
144
- promise.reject("EUNSPECIFIED", "Error parsing order: ${e.message}")
145
- return
146
- }
147
- val limit = options?.getIntIfPresent("limit")
148
- val preview = options?.getBooleanIfPresent("preview")
149
- val language = options?.getStringIfPresent("language")
150
- val fields = try {
151
- convertReadableArrayToKJsonList(options?.getArray("fields"))
152
- } catch (e: Exception) {
153
- DashXLog.d(tag, e.message)
154
- promise.reject("EUNSPECIFIED", "Error parsing fields: ${e.message}")
155
- return
156
- }
157
- val include = try {
158
- convertReadableArrayToKJsonList(options?.getArray("include"))
159
- } catch (e: Exception) {
160
- DashXLog.d(tag, e.message)
161
- promise.reject("EUNSPECIFIED", "Error parsing include: ${e.message}")
162
- return
163
- }
164
- val exclude = try {
165
- convertReadableArrayToKJsonList(options?.getArray("exclude"))
166
- } catch (e: Exception) {
167
- DashXLog.d(tag, e.message)
168
- promise.reject("EUNSPECIFIED", "Error parsing exclude: ${e.message}")
169
- return
170
- }
171
-
172
- DashX.searchRecords(
173
- resource = resource,
174
- filter = jsonFilter,
175
- order = order,
176
- limit = limit,
177
- preview = preview,
178
- language = language,
179
- fields = fields,
180
- include = include,
181
- exclude = exclude,
182
- onError = {
183
- promise.reject("EUNSPECIFIED", it.message)
184
- },
185
- onSuccess = { records ->
186
- val readableArray = Arguments.createArray()
187
- records.forEach {
188
- readableArray.pushMap(convertJsonToMap(convertKJsonToJson(it)))
189
- }
190
- promise.resolve(readableArray)
191
- }
192
- )
193
- }
194
-
195
- @ReactMethod
196
- fun fetchStoredPreferences(promise: Promise) {
197
- DashX.fetchStoredPreferences(
198
- onError = {
199
- promise.reject("EUNSPECIFIED", it.message)
200
- },
201
- onSuccess = { content ->
202
- promise.resolve(convertJsonToMap(convertKJsonToJson(Json.decodeFromString<JsonObject>(Json.encodeToString(content)))))
203
- }
204
- )
205
- }
206
-
207
- @ReactMethod
208
- fun saveStoredPreferences(preferenceData: ReadableMap?, promise: Promise) {
209
- val preferencesString = MapUtil.toJSONElement(preferenceData).toString()
210
-
211
- DashX.saveStoredPreferences(
212
- Json.decodeFromString<JsonObject>(preferencesString),
213
- onError = {
214
- promise.reject("EUNSPECIFIED", it.message)
215
- },
216
- onSuccess = { content ->
217
- promise.resolve(convertJsonToMap(convertKJsonToJson(Json.decodeFromString<JsonObject>(Json.encodeToString(content)))))
218
- }
219
- )
220
- }
221
-
222
- @ReactMethod
223
- fun subscribe() {
224
- DashX.subscribe()
225
- }
226
-
227
- @ReactMethod
228
- fun unsubscribe() {
229
- DashX.unsubscribe()
230
- }
231
- }
@@ -1,18 +0,0 @@
1
- package com.dashx.rn.sdk
2
-
3
- import com.facebook.react.ReactPackage
4
- import com.facebook.react.bridge.JavaScriptModule
5
- import com.facebook.react.bridge.NativeModule
6
- import com.facebook.react.bridge.ReactApplicationContext
7
- import com.facebook.react.uimanager.ViewManager
8
- import java.util.Arrays
9
-
10
- class DashXPackage : ReactPackage {
11
- override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
12
- return Arrays.asList<NativeModule>(DashXReactNativeModule(reactContext))
13
- }
14
-
15
- override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
16
- return emptyList()
17
- }
18
- }
@@ -1,3 +0,0 @@
1
- #import <UIKit/UIKit.h>
2
- #import <React/RCTBundleURLProvider.h>
3
- #import <React_RCTAppDelegate/RCTAppDelegate.h>
@@ -1,266 +0,0 @@
1
- import Foundation
2
- import UIKit
3
- import DashX
4
- #if canImport(FirebaseCore)
5
- import FirebaseCore
6
- #endif
7
- #if canImport(FirebaseMessaging)
8
- import FirebaseMessaging
9
- #endif
10
-
11
- @objc(DashXRCTAppDelegate)
12
- open class DashXRCTAppDelegate: RCTDefaultReactNativeFactoryDelegate, UIApplicationDelegate, UNUserNotificationCenterDelegate {
13
-
14
- public var window: UIWindow?
15
- private var reactNativeFactory: RCTReactNativeFactory?
16
-
17
- /// The React Native module name. Defaults to "main". Override to match your app's registered component name.
18
- open var moduleName: String { "main" }
19
-
20
- // MARK: - UIApplicationDelegate
21
-
22
- open func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
23
- #if canImport(FirebaseCore)
24
- FirebaseApp.configure()
25
- #endif
26
- #if canImport(FirebaseMessaging)
27
- Messaging.messaging().delegate = self
28
- #endif
29
-
30
- UNUserNotificationCenter.current().delegate = self
31
-
32
- DashX.requestNotificationPermission { authorizationStatus in
33
- switch authorizationStatus {
34
- case .authorized:
35
- DashXLog.d(tag: #function, "permission authorized to receive push notifications")
36
- DispatchQueue.main.async {
37
- application.registerForRemoteNotifications()
38
- }
39
- default:
40
- DashXLog.d(tag: #function, "permission denied to receive push notifications")
41
- }
42
- }
43
-
44
- let factory = RCTReactNativeFactory(delegate: self)
45
- reactNativeFactory = factory
46
-
47
- window = UIWindow(frame: UIScreen.main.bounds)
48
- factory.startReactNative(withModuleName: moduleName, in: window, launchOptions: launchOptions)
49
-
50
- return true
51
- }
52
-
53
- // MARK: - APNS Token Management
54
-
55
- open func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
56
- DashXLog.d(tag: #function, "Unable to register for remote notifications: \(error.localizedDescription)")
57
- }
58
-
59
- open func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
60
- #if canImport(FirebaseMessaging)
61
- Messaging.messaging().setAPNSToken(deviceToken, type: .unknown)
62
- Messaging.messaging().token { token, error in
63
- if let token = token {
64
- DashX.setFCMToken(to: token)
65
- }
66
- }
67
- #endif
68
- }
69
-
70
- // MARK: - Universal Links
71
-
72
- open func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
73
- DashX.handleUserActivity(userActivity: userActivity)
74
- return true
75
- }
76
-
77
- // MARK: - Push Notifications
78
-
79
- open func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
80
- let message = notification.request.content.userInfo
81
-
82
- #if canImport(FirebaseMessaging)
83
- Messaging.messaging().appDidReceiveMessage(message)
84
- #endif
85
-
86
- DashX.trackMessage(message: message, event: .delivered)
87
-
88
- DashXEventEmitter.instance.dispatch(name: "messageReceived", body: bridgeSafePayload(from: message))
89
-
90
- completionHandler(notificationDeliveredInForeground(message: message))
91
- }
92
-
93
- open func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
94
- let message = response.notification.request.content.userInfo
95
-
96
- #if canImport(FirebaseMessaging)
97
- Messaging.messaging().appDidReceiveMessage(message)
98
- #endif
99
-
100
- DashXEventEmitter.instance.dispatch(name: "messageReceived", body: bridgeSafePayload(from: message))
101
-
102
- if response.actionIdentifier == UNNotificationDismissActionIdentifier {
103
- DashX.trackMessage(message: message, event: .dismissed)
104
- } else {
105
- DashX.trackMessage(message: message, event: .clicked)
106
-
107
- if let url = message.dashxNotificationUrl() {
108
- handleLink(url: url)
109
- } else {
110
- notificationClicked(message: message, actionIdentifier: response.actionIdentifier)
111
- }
112
- }
113
-
114
- completionHandler()
115
- }
116
-
117
- open func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
118
- #if canImport(FirebaseMessaging)
119
- Messaging.messaging().appDidReceiveMessage(userInfo)
120
- #endif
121
-
122
- DashXEventEmitter.instance.dispatch(name: "messageReceived", body: bridgeSafePayload(from: userInfo))
123
-
124
- guard let dashxData = userInfo.dashxNotificationData() else {
125
- DashXLog.d(tag: #function, "Unable to parse DashX notification data")
126
- completionHandler(.failed)
127
- return
128
- }
129
-
130
- let notificationContent = UNMutableNotificationContent()
131
- notificationContent.sound = UNNotificationSound.default
132
- notificationContent.title = dashxData.title
133
- notificationContent.body = dashxData.body
134
- notificationContent.userInfo = userInfo
135
- notificationContent.categoryIdentifier = Constants.DASHX_NOTIFICATION_CATEGORY_IDENTIFIER
136
-
137
- var notificationActions: [UNNotificationAction] = []
138
-
139
- if let actionButtons = dashxData.actionButtons {
140
- for button in actionButtons {
141
- notificationActions.append(
142
- UNNotificationAction(
143
- identifier: button.identifier,
144
- title: button.label,
145
- options: [.foreground]
146
- )
147
- )
148
- }
149
- }
150
-
151
- let notificationCategory = UNNotificationCategory(
152
- identifier: Constants.DASHX_NOTIFICATION_CATEGORY_IDENTIFIER,
153
- actions: notificationActions,
154
- intentIdentifiers: [],
155
- options: .customDismissAction
156
- )
157
-
158
- UNUserNotificationCenter.current().setNotificationCategories([notificationCategory])
159
-
160
- if let imagePath = dashxData.image,
161
- let imageURL = URL(string: imagePath)
162
- {
163
- createNotificationWithImage(id: dashxData.id, imageURL: imageURL, content: notificationContent)
164
- } else {
165
- createNotification(id: dashxData.id, content: notificationContent)
166
- }
167
-
168
- completionHandler(.newData)
169
- }
170
-
171
- // MARK: - Override points
172
-
173
- open func notificationDeliveredInForeground(message: [AnyHashable: Any]) -> UNNotificationPresentationOptions { return [.banner, .sound] }
174
-
175
- open func notificationClicked(message: [AnyHashable: Any], actionIdentifier: String) {}
176
-
177
- open func handleLink(url: URL) {}
178
-
179
- // MARK: - Helpers
180
-
181
- private func bridgeSafePayload(from userInfo: [AnyHashable: Any]) -> [String: Any] {
182
- userInfo.reduce(into: [String: Any]()) { result, pair in
183
- let key = String(describing: pair.key)
184
- let value = pair.value
185
- if let str = value as? String {
186
- result[key] = str
187
- } else if let num = value as? NSNumber {
188
- result[key] = num
189
- } else if let dict = value as? [AnyHashable: Any] {
190
- result[key] = bridgeSafePayload(from: dict)
191
- } else if let arr = value as? [Any] {
192
- result[key] = arr.map { item -> Any in
193
- if let str = item as? String { return str }
194
- if let num = item as? NSNumber { return num }
195
- if let d = item as? [AnyHashable: Any] { return bridgeSafePayload(from: d) }
196
- if let a = item as? [Any] {
197
- return a.map { sub -> Any in
198
- if let s = sub as? String { return s }
199
- if let n = sub as? NSNumber { return n }
200
- if let sd = sub as? [AnyHashable: Any] { return bridgeSafePayload(from: sd) }
201
- return "\(sub)"
202
- }
203
- }
204
- return "\(item)"
205
- }
206
- } else {
207
- result[key] = "\(value)"
208
- }
209
- }
210
- }
211
- }
212
-
213
- extension DashXRCTAppDelegate {
214
- private func createNotification(id: String, content: UNMutableNotificationContent) {
215
- let request = UNNotificationRequest(identifier: id, content: content, trigger: nil)
216
-
217
- UNUserNotificationCenter.current().add(request) { error in
218
- if let error = error {
219
- DashXLog.d(tag: #function, "Failed to schedule notification request: \(error.localizedDescription)")
220
- } else {
221
- DashXLog.d(tag: #function, "Notification request added successfully.")
222
- }
223
- }
224
- }
225
-
226
- private func createNotificationWithImage(id: String,
227
- imageURL: URL,
228
- content: UNMutableNotificationContent)
229
- {
230
- let task = URLSession.shared.downloadTask(with: imageURL) { location, _, error in
231
- guard let location = location, error == nil else {
232
- return
233
- }
234
-
235
- let tmpDirectoryURL = FileManager.default.temporaryDirectory
236
- let uuid = UUID().uuidString
237
- let tmpFileURL = tmpDirectoryURL.appendingPathComponent(uuid + ".png")
238
-
239
- do {
240
- try FileManager.default.moveItem(at: location, to: tmpFileURL)
241
-
242
- let attachment = try UNNotificationAttachment(identifier: "\(id)-attachment", url: tmpFileURL, options: nil)
243
- content.attachments = [attachment]
244
- self.createNotification(id: id, content: content)
245
- } catch {
246
- DashXLog.d(tag: #function, "Error moving file: \(error.localizedDescription)")
247
- }
248
- }
249
- task.resume()
250
- }
251
- }
252
-
253
- #if canImport(FirebaseMessaging)
254
- extension DashXRCTAppDelegate: MessagingDelegate {
255
- open func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
256
- guard let token = fcmToken else {
257
- DashXLog.d(tag: #function, "FCM Token is empty")
258
- return
259
- }
260
-
261
- DashXLog.d(tag: #function, "FCM Token: \(token)")
262
-
263
- DashX.setFCMToken(to: token)
264
- }
265
- }
266
- #endif
@@ -1 +0,0 @@
1
- #import "DashXRCTAppDelegate.h"