@dashx/react-native 1.1.1 → 1.1.3
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/.DS_Store +0 -0
- package/.claude/settings.local.json +14 -0
- package/.github/workflows/ci.yml +28 -0
- package/CONTRIBUTING.md +153 -0
- package/DashXReactNative.podspec +6 -2
- package/README.md +259 -97
- package/__tests__/index.test.js +363 -0
- package/android/.gitignore +10 -0
- package/android/.gradle/7.2/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/7.2/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/7.2/fileChanges/last-build.bin +0 -0
- package/android/.gradle/7.2/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/7.2/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/checksums/checksums.lock +0 -0
- package/android/.gradle/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/build/.transforms/9dceace6c3787533d2dbb1a387e9284c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/dashx/rn/sdk/DashXReactNativeFirebaseMessagingService.dex +0 -0
- package/android/build/.transforms/9dceace6c3787533d2dbb1a387e9284c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/dashx/rn/sdk/DashXReactNativeModule.dex +0 -0
- package/android/build/.transforms/9dceace6c3787533d2dbb1a387e9284c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/dashx/rn/sdk/MessageReceivedEventHolder.dex +0 -0
- package/android/build/.transforms/9dceace6c3787533d2dbb1a387e9284c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/dashx/rn/sdk/util/Utils$WhenMappings.dex +0 -0
- package/android/build/.transforms/9dceace6c3787533d2dbb1a387e9284c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/dashx/rn/sdk/util/Utils.dex +0 -0
- package/android/build/.transforms/9dceace6c3787533d2dbb1a387e9284c/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
- package/android/build/.transforms/f3c6049e7ab4bb564c79f3a246b8575e/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +16 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +31 -5
- package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +16 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/dashx/rn/sdk/DashXReactNativeFirebaseMessagingService.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/dashx/rn/sdk/DashXReactNativeModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/dashx/rn/sdk/MessageReceivedEventHolder.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/dashx/rn/sdk/util/Utils$WhenMappings.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/dashx/rn/sdk/util/Utils.class +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +1 -1
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +25 -3
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/dashx/rn/sdk/DashXReactNativeFirebaseMessagingService.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/dashx/rn/sdk/DashXReactNativeModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/dashx/rn/sdk/MessageReceivedEventHolder.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/dashx/rn/sdk/util/Utils$WhenMappings.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/dashx/rn/sdk/util/Utils.class +0 -0
- package/android/build.gradle +4 -1
- package/android/src/main/AndroidManifest.xml +15 -3
- package/android/src/main/java/com/dashx/rn/sdk/DashXReactNativeFirebaseMessagingService.kt +72 -0
- package/android/src/main/java/com/dashx/rn/sdk/DashXReactNativeModule.kt +84 -15
- package/android/src/main/java/com/dashx/rn/sdk/MessageReceivedEventHolder.kt +14 -0
- package/android/src/main/java/com/dashx/rn/sdk/util/Utils.kt +14 -0
- package/babel.config.js +1 -1
- package/index.d.ts +107 -0
- package/index.js +81 -4
- package/ios/.DS_Store +0 -0
- package/ios/DashXEventEmitter.swift +3 -2
- package/ios/DashXRCTAppDelegate.swift +110 -44
- package/ios/DashXReactNative-Bridging-Header.h +2 -0
- package/ios/DashXReactNative.h +1 -0
- package/ios/DashXReactNative.mm +16 -0
- package/ios/DashXReactNative.swift +118 -28
- package/package.json +18 -5
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class DashXEventEmitter {
|
|
2
2
|
static let instance = DashXEventEmitter()
|
|
3
|
-
private static var eventEmitter: DashXReactNative
|
|
3
|
+
private static var eventEmitter: DashXReactNative?
|
|
4
4
|
|
|
5
5
|
private init() {}
|
|
6
6
|
|
|
@@ -9,6 +9,7 @@ class DashXEventEmitter {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
func dispatch(name: String, body: Any?) {
|
|
12
|
-
DashXEventEmitter.eventEmitter
|
|
12
|
+
guard let emitter = DashXEventEmitter.eventEmitter else { return }
|
|
13
|
+
emitter.sendEvent(withName: name, body: body)
|
|
13
14
|
}
|
|
14
15
|
}
|
|
@@ -1,90 +1,108 @@
|
|
|
1
|
-
import FirebaseCore
|
|
2
|
-
import FirebaseMessaging
|
|
3
1
|
import Foundation
|
|
4
2
|
import UIKit
|
|
5
3
|
import DashX
|
|
4
|
+
#if canImport(FirebaseCore)
|
|
5
|
+
import FirebaseCore
|
|
6
|
+
#endif
|
|
7
|
+
#if canImport(FirebaseMessaging)
|
|
8
|
+
import FirebaseMessaging
|
|
9
|
+
#endif
|
|
6
10
|
|
|
7
11
|
@objc(DashXRCTAppDelegate)
|
|
8
|
-
open class DashXRCTAppDelegate:
|
|
9
|
-
// MARK: Getters
|
|
10
|
-
private var app: UIApplication = .shared
|
|
11
|
-
|
|
12
|
-
// MARK: Init
|
|
12
|
+
open class DashXRCTAppDelegate: RCTDefaultReactNativeFactoryDelegate, UIApplicationDelegate, UNUserNotificationCenterDelegate {
|
|
13
13
|
|
|
14
|
-
public
|
|
15
|
-
|
|
14
|
+
public var window: UIWindow?
|
|
15
|
+
private var reactNativeFactory: RCTReactNativeFactory?
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// Register to ensure device token can be fetched
|
|
20
|
-
app.registerForRemoteNotifications()
|
|
21
|
-
}
|
|
17
|
+
/// The React Native module name. Defaults to "main". Override to match your app's registered component name.
|
|
18
|
+
open var moduleName: String { "main" }
|
|
22
19
|
|
|
23
|
-
// MARK:
|
|
20
|
+
// MARK: - UIApplicationDelegate
|
|
24
21
|
|
|
25
|
-
open
|
|
22
|
+
open func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
|
23
|
+
#if canImport(FirebaseCore)
|
|
26
24
|
FirebaseApp.configure()
|
|
25
|
+
#endif
|
|
26
|
+
#if canImport(FirebaseMessaging)
|
|
27
27
|
Messaging.messaging().delegate = self
|
|
28
|
+
#endif
|
|
29
|
+
|
|
30
|
+
UNUserNotificationCenter.current().delegate = self
|
|
28
31
|
|
|
29
|
-
// Requesting Push Notifications Permission
|
|
30
32
|
DashX.requestNotificationPermission { authorizationStatus in
|
|
31
33
|
switch authorizationStatus {
|
|
32
34
|
case .authorized:
|
|
33
35
|
DashXLog.d(tag: #function, "permission authorized to receive push notifications")
|
|
36
|
+
DispatchQueue.main.async {
|
|
37
|
+
application.registerForRemoteNotifications()
|
|
38
|
+
}
|
|
34
39
|
default:
|
|
35
40
|
DashXLog.d(tag: #function, "permission denied to receive push notifications")
|
|
36
41
|
}
|
|
37
42
|
}
|
|
38
43
|
|
|
39
|
-
|
|
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
|
|
40
51
|
}
|
|
41
52
|
|
|
42
53
|
// MARK: - APNS Token Management
|
|
43
54
|
|
|
44
|
-
|
|
55
|
+
open func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
|
|
45
56
|
DashXLog.d(tag: #function, "Unable to register for remote notifications: \(error.localizedDescription)")
|
|
46
57
|
}
|
|
47
58
|
|
|
48
|
-
|
|
59
|
+
open func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
|
60
|
+
#if canImport(FirebaseMessaging)
|
|
49
61
|
Messaging.messaging().setAPNSToken(deviceToken, type: .unknown)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
DashXLog.d(tag: #function, "FCM Token is empty")
|
|
55
|
-
return
|
|
62
|
+
Messaging.messaging().token { token, error in
|
|
63
|
+
if let token = token {
|
|
64
|
+
DashX.setFCMToken(to: token)
|
|
65
|
+
}
|
|
56
66
|
}
|
|
67
|
+
#endif
|
|
68
|
+
}
|
|
57
69
|
|
|
58
|
-
|
|
70
|
+
// MARK: - Universal Links
|
|
59
71
|
|
|
60
|
-
|
|
72
|
+
open func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
|
|
73
|
+
DashX.handleUserActivity(userActivity: userActivity)
|
|
74
|
+
return true
|
|
61
75
|
}
|
|
62
76
|
|
|
63
77
|
// MARK: - Push Notifications
|
|
64
78
|
|
|
65
|
-
|
|
79
|
+
open func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
|
|
66
80
|
let message = notification.request.content.userInfo
|
|
67
81
|
|
|
68
|
-
|
|
82
|
+
#if canImport(FirebaseMessaging)
|
|
69
83
|
Messaging.messaging().appDidReceiveMessage(message)
|
|
84
|
+
#endif
|
|
70
85
|
|
|
71
|
-
DashX.
|
|
86
|
+
DashX.trackMessage(message: message, event: .delivered)
|
|
72
87
|
|
|
73
|
-
|
|
88
|
+
DashXEventEmitter.instance.dispatch(name: "messageReceived", body: bridgeSafePayload(from: message))
|
|
74
89
|
|
|
75
|
-
completionHandler(
|
|
90
|
+
completionHandler(notificationDeliveredInForeground(message: message))
|
|
76
91
|
}
|
|
77
92
|
|
|
78
|
-
|
|
93
|
+
open func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
|
|
79
94
|
let message = response.notification.request.content.userInfo
|
|
80
95
|
|
|
81
|
-
|
|
96
|
+
#if canImport(FirebaseMessaging)
|
|
82
97
|
Messaging.messaging().appDidReceiveMessage(message)
|
|
98
|
+
#endif
|
|
99
|
+
|
|
100
|
+
DashXEventEmitter.instance.dispatch(name: "messageReceived", body: bridgeSafePayload(from: message))
|
|
83
101
|
|
|
84
102
|
if response.actionIdentifier == UNNotificationDismissActionIdentifier {
|
|
85
|
-
DashX.
|
|
103
|
+
DashX.trackMessage(message: message, event: .dismissed)
|
|
86
104
|
} else {
|
|
87
|
-
DashX.
|
|
105
|
+
DashX.trackMessage(message: message, event: .clicked)
|
|
88
106
|
|
|
89
107
|
if let url = message.dashxNotificationUrl() {
|
|
90
108
|
handleLink(url: url)
|
|
@@ -96,9 +114,12 @@ open class DashXRCTAppDelegate: RCTAppDelegate, MessagingDelegate, UNUserNotific
|
|
|
96
114
|
completionHandler()
|
|
97
115
|
}
|
|
98
116
|
|
|
99
|
-
|
|
100
|
-
|
|
117
|
+
open func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
|
|
118
|
+
#if canImport(FirebaseMessaging)
|
|
101
119
|
Messaging.messaging().appDidReceiveMessage(userInfo)
|
|
120
|
+
#endif
|
|
121
|
+
|
|
122
|
+
DashXEventEmitter.instance.dispatch(name: "messageReceived", body: bridgeSafePayload(from: userInfo))
|
|
102
123
|
|
|
103
124
|
guard let dashxData = userInfo.dashxNotificationData() else {
|
|
104
125
|
DashXLog.d(tag: #function, "Unable to parse DashX notification data")
|
|
@@ -147,13 +168,46 @@ open class DashXRCTAppDelegate: RCTAppDelegate, MessagingDelegate, UNUserNotific
|
|
|
147
168
|
completionHandler(.newData)
|
|
148
169
|
}
|
|
149
170
|
|
|
150
|
-
// MARK: -
|
|
171
|
+
// MARK: - Override points
|
|
151
172
|
|
|
152
|
-
open func notificationDeliveredInForeground(message: [AnyHashable: Any]) -> UNNotificationPresentationOptions { return [] }
|
|
173
|
+
open func notificationDeliveredInForeground(message: [AnyHashable: Any]) -> UNNotificationPresentationOptions { return [.banner, .sound] }
|
|
153
174
|
|
|
154
175
|
open func notificationClicked(message: [AnyHashable: Any], actionIdentifier: String) {}
|
|
155
176
|
|
|
156
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
|
+
}
|
|
157
211
|
}
|
|
158
212
|
|
|
159
213
|
extension DashXRCTAppDelegate {
|
|
@@ -178,16 +232,13 @@ extension DashXRCTAppDelegate {
|
|
|
178
232
|
return
|
|
179
233
|
}
|
|
180
234
|
|
|
181
|
-
// Create a temporary file URL to save the downloaded image
|
|
182
235
|
let tmpDirectoryURL = FileManager.default.temporaryDirectory
|
|
183
236
|
let uuid = UUID().uuidString
|
|
184
237
|
let tmpFileURL = tmpDirectoryURL.appendingPathComponent(uuid + ".png")
|
|
185
238
|
|
|
186
239
|
do {
|
|
187
|
-
// Move the downloaded file to the temporary file URL
|
|
188
240
|
try FileManager.default.moveItem(at: location, to: tmpFileURL)
|
|
189
241
|
|
|
190
|
-
// Create the notification attachment from the temporary file URL
|
|
191
242
|
let attachment = try UNNotificationAttachment(identifier: "\(id)-attachment", url: tmpFileURL, options: nil)
|
|
192
243
|
content.attachments = [attachment]
|
|
193
244
|
self.createNotification(id: id, content: content)
|
|
@@ -198,3 +249,18 @@ extension DashXRCTAppDelegate {
|
|
|
198
249
|
task.resume()
|
|
199
250
|
}
|
|
200
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#import "DashXRCTAppDelegate.h"
|
package/ios/DashXReactNative.mm
CHANGED
|
@@ -13,6 +13,10 @@ RCT_EXTERN_METHOD(track:(NSString *)event data:(NSDictionary * _Nullable)data);
|
|
|
13
13
|
|
|
14
14
|
RCT_EXTERN_METHOD(screen:(NSString *)screenName data:(NSDictionary * _Nullable)data);
|
|
15
15
|
|
|
16
|
+
RCT_EXTERN_METHOD(fetchRecord:(NSString *)urn options:(NSDictionary * _Nullable)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject);
|
|
17
|
+
|
|
18
|
+
RCT_EXTERN_METHOD(searchRecords:(NSString *)resource options:(NSDictionary * _Nullable)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject);
|
|
19
|
+
|
|
16
20
|
RCT_EXTERN_METHOD(fetchStoredPreferences:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject);
|
|
17
21
|
|
|
18
22
|
RCT_EXTERN_METHOD(saveStoredPreferences:(NSDictionary *)preferenceData resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject);
|
|
@@ -25,4 +29,16 @@ RCT_EXTERN_METHOD(unsubscribe);
|
|
|
25
29
|
|
|
26
30
|
RCT_EXTERN_METHOD(setLogLevel:(int *)level);
|
|
27
31
|
|
|
32
|
+
RCT_EXTERN_METHOD(uploadAsset:(NSString *)filePath resource:(NSString *)resource attribute:(NSString *)attribute resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject);
|
|
33
|
+
|
|
34
|
+
RCT_EXTERN_METHOD(fetchAsset:(NSString *)assetId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject);
|
|
35
|
+
|
|
36
|
+
RCT_EXTERN_METHOD(enableLifecycleTracking);
|
|
37
|
+
|
|
38
|
+
RCT_EXTERN_METHOD(enableAdTracking);
|
|
39
|
+
|
|
40
|
+
RCT_EXTERN_METHOD(requestNotificationPermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject);
|
|
41
|
+
|
|
42
|
+
RCT_EXTERN_METHOD(getNotificationPermissionStatus:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject);
|
|
43
|
+
|
|
28
44
|
@end
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import DashX
|
|
3
3
|
|
|
4
|
-
typealias CBU = CallbackUtils
|
|
5
|
-
|
|
6
4
|
@objc(DashXReactNative)
|
|
7
5
|
class DashXReactNative: RCTEventEmitter {
|
|
8
6
|
override init() {
|
|
9
7
|
super.init()
|
|
10
8
|
DashXEventEmitter.instance.registerEventEmitter(eventEmitter: self)
|
|
9
|
+
DashX.linkHandler = { url in
|
|
10
|
+
DashXEventEmitter.instance.dispatch(name: "linkReceived", body: url.absoluteString)
|
|
11
|
+
}
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
override static func requiresMainQueueSetup() -> Bool {
|
|
@@ -15,14 +16,16 @@ class DashXReactNative: RCTEventEmitter {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
override func supportedEvents() -> [String] {
|
|
18
|
-
return ["messageReceived"]
|
|
19
|
+
return ["messageReceived", "linkReceived"]
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
@objc(configure:)
|
|
22
23
|
func configure(_ options: NSDictionary) {
|
|
23
|
-
let publicKey = options["publicKey"] as
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
guard let publicKey = options["publicKey"] as? String, !publicKey.isEmpty else {
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
let baseURI = options["baseURI"] as? String
|
|
28
|
+
let targetEnvironment = options["targetEnvironment"] as? String
|
|
26
29
|
|
|
27
30
|
DashX.configure(
|
|
28
31
|
withPublicKey: publicKey,
|
|
@@ -33,7 +36,8 @@ class DashXReactNative: RCTEventEmitter {
|
|
|
33
36
|
|
|
34
37
|
@objc(identify:)
|
|
35
38
|
func identify(_ options: NSDictionary) {
|
|
36
|
-
|
|
39
|
+
let stringOptions = (options as? [String: Any])?.compactMapValues { ($0 as? CustomStringConvertible)?.description } ?? [:]
|
|
40
|
+
try? DashX.identify(options: stringOptions)
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
@objc(setIdentity:token:)
|
|
@@ -48,29 +52,74 @@ class DashXReactNative: RCTEventEmitter {
|
|
|
48
52
|
|
|
49
53
|
@objc(track:data:)
|
|
50
54
|
func track(_ event: String, _ data: NSDictionary?) {
|
|
51
|
-
DashX.track(event, withData: data)
|
|
55
|
+
DashX.track(event, withData: data as? [String: Any])
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
@objc(screen:data:)
|
|
55
59
|
func screen(_ screenName: String, _ data: NSDictionary?) {
|
|
56
|
-
DashX.screen(screenName, withData: data)
|
|
60
|
+
DashX.screen(screenName, withData: data as? [String: Any])
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@objc(fetchRecord:options:resolver:rejecter:)
|
|
64
|
+
func fetchRecord(_ urn: String, options: NSDictionary?, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
65
|
+
DashXClient.instance.fetchRecord(
|
|
66
|
+
urn: urn,
|
|
67
|
+
preview: options?["preview"] as? Bool,
|
|
68
|
+
language: options?["language"] as? String,
|
|
69
|
+
fields: options?["fields"] as? [[String: Any]],
|
|
70
|
+
include: options?["include"] as? [[String: Any]],
|
|
71
|
+
exclude: options?["exclude"] as? [[String: Any]]
|
|
72
|
+
) { result in
|
|
73
|
+
switch result {
|
|
74
|
+
case .success(let record): resolve(record)
|
|
75
|
+
case .failure(let error): reject("EUNSPECIFIED", error.localizedDescription, error)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@objc(searchRecords:options:resolver:rejecter:)
|
|
81
|
+
func searchRecords(_ resource: String, options: NSDictionary?, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
82
|
+
DashXClient.instance.searchRecords(
|
|
83
|
+
resource: resource,
|
|
84
|
+
filter: options?["filter"] as? [String: Any],
|
|
85
|
+
order: options?["order"] as? [[String: Any]],
|
|
86
|
+
limit: options?["limit"] as? Int,
|
|
87
|
+
page: options?["page"] as? Int,
|
|
88
|
+
preview: options?["preview"] as? Bool,
|
|
89
|
+
language: options?["language"] as? String,
|
|
90
|
+
fields: options?["fields"] as? [[String: Any]],
|
|
91
|
+
include: options?["include"] as? [[String: Any]],
|
|
92
|
+
exclude: options?["exclude"] as? [[String: Any]]
|
|
93
|
+
) { result in
|
|
94
|
+
switch result {
|
|
95
|
+
case .success(let records): resolve(records)
|
|
96
|
+
case .failure(let error): reject("EUNSPECIFIED", error.localizedDescription, error)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
57
99
|
}
|
|
58
100
|
|
|
59
101
|
@objc(fetchStoredPreferences:rejecter:)
|
|
60
102
|
func fetchStoredPreferences(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
103
|
+
DashXClient.instance.fetchStoredPreferences { result in
|
|
104
|
+
switch result {
|
|
105
|
+
case .success(let prefs): resolve(prefs)
|
|
106
|
+
case .failure(let error): reject("EUNSPECIFIED", error.localizedDescription, error)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
65
109
|
}
|
|
66
110
|
|
|
67
|
-
@objc(saveStoredPreferences:
|
|
68
|
-
func saveStoredPreferences(_ preferenceData: NSDictionary,
|
|
69
|
-
|
|
70
|
-
preferenceData
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
)
|
|
111
|
+
@objc(saveStoredPreferences:resolver:rejecter:)
|
|
112
|
+
func saveStoredPreferences(_ preferenceData: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
113
|
+
guard let dict = preferenceData as? [String: Any] else {
|
|
114
|
+
reject("EINVAL", "preferenceData must be a plain object", nil)
|
|
115
|
+
return
|
|
116
|
+
}
|
|
117
|
+
DashXClient.instance.saveStoredPreferences(preferenceData: dict) { result in
|
|
118
|
+
switch result {
|
|
119
|
+
case .success(let success): resolve(success)
|
|
120
|
+
case .failure(let error): reject("EUNSPECIFIED", error.localizedDescription, error)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
74
123
|
}
|
|
75
124
|
|
|
76
125
|
@objc
|
|
@@ -88,18 +137,59 @@ class DashXReactNative: RCTEventEmitter {
|
|
|
88
137
|
let logLevel = DashXLog.LogLevel(rawValue: level) ?? DashXLog.LogLevel.off
|
|
89
138
|
DashXLog.setLogLevel(to: logLevel)
|
|
90
139
|
}
|
|
91
|
-
}
|
|
92
140
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
141
|
+
@objc(uploadAsset:resource:attribute:resolver:rejecter:)
|
|
142
|
+
func uploadAsset(_ filePath: String, resource: String, attribute: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
143
|
+
let fileURL = URL(fileURLWithPath: filePath)
|
|
144
|
+
DashXClient.instance.uploadAsset(fileURL: fileURL, resource: resource, attribute: attribute) { result in
|
|
145
|
+
switch result {
|
|
146
|
+
case .success(let assetResponse):
|
|
147
|
+
if let data = try? JSONEncoder().encode(assetResponse),
|
|
148
|
+
let dict = try? JSONSerialization.jsonObject(with: data) as? NSDictionary {
|
|
149
|
+
resolve(dict)
|
|
150
|
+
} else {
|
|
151
|
+
resolve(nil)
|
|
152
|
+
}
|
|
153
|
+
case .failure(let error):
|
|
154
|
+
reject("EUNSPECIFIED", error.localizedDescription, error)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
96
157
|
}
|
|
97
158
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
159
|
+
@objc(fetchAsset:resolver:rejecter:)
|
|
160
|
+
func fetchAsset(_ assetId: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
161
|
+
DashXClient.instance.fetchAsset(assetId: assetId) { result in
|
|
162
|
+
switch result {
|
|
163
|
+
case .success(let assetResponse):
|
|
164
|
+
if let data = try? JSONEncoder().encode(assetResponse),
|
|
165
|
+
let dict = try? JSONSerialization.jsonObject(with: data) as? NSDictionary {
|
|
166
|
+
resolve(dict)
|
|
167
|
+
} else {
|
|
168
|
+
resolve(nil)
|
|
169
|
+
}
|
|
170
|
+
case .failure(let error):
|
|
171
|
+
reject("EUNSPECIFIED", error.localizedDescription, error)
|
|
172
|
+
}
|
|
101
173
|
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@objc
|
|
177
|
+
func enableLifecycleTracking() {
|
|
178
|
+
DispatchQueue.main.async { DashX.enableLifecycleTracking() }
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@objc
|
|
182
|
+
func enableAdTracking() {
|
|
183
|
+
DashX.enableAdTracking()
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@objc(requestNotificationPermission:rejecter:)
|
|
187
|
+
func requestNotificationPermission(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
188
|
+
DashX.requestNotificationPermission { status in resolve(status.rawValue) }
|
|
189
|
+
}
|
|
102
190
|
|
|
103
|
-
|
|
191
|
+
@objc(getNotificationPermissionStatus:rejecter:)
|
|
192
|
+
func getNotificationPermissionStatus(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
193
|
+
DashX.getNotificationPermissionStatus { status in resolve(status.rawValue) }
|
|
104
194
|
}
|
|
105
195
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dashx/react-native",
|
|
3
3
|
"title": "DashX React Native",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.3",
|
|
5
5
|
"description": "DashX SDK for React Native",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"types": "index.d.ts",
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
"README.md"
|
|
26
26
|
],
|
|
27
27
|
"scripts": {
|
|
28
|
-
"test": "
|
|
28
|
+
"test": "jest",
|
|
29
|
+
"lint": "eslint index.js"
|
|
29
30
|
},
|
|
30
31
|
"repository": {
|
|
31
32
|
"type": "git",
|
|
@@ -37,7 +38,7 @@
|
|
|
37
38
|
"android"
|
|
38
39
|
],
|
|
39
40
|
"author": {
|
|
40
|
-
"name": "
|
|
41
|
+
"name": "Team DashX",
|
|
41
42
|
"email": "dev@dashx.com"
|
|
42
43
|
},
|
|
43
44
|
"license": "MIT",
|
|
@@ -47,8 +48,8 @@
|
|
|
47
48
|
"registry": "https://registry.npmjs.org/"
|
|
48
49
|
},
|
|
49
50
|
"peerDependencies": {
|
|
50
|
-
"react": "
|
|
51
|
-
"react-native": "
|
|
51
|
+
"react": ">=17.0.0",
|
|
52
|
+
"react-native": ">=0.71.0"
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
54
55
|
"@commitlint/config-conventional": "^17.0.2",
|
|
@@ -74,6 +75,9 @@
|
|
|
74
75
|
"@react-native",
|
|
75
76
|
"prettier"
|
|
76
77
|
],
|
|
78
|
+
"plugins": [
|
|
79
|
+
"prettier"
|
|
80
|
+
],
|
|
77
81
|
"rules": {
|
|
78
82
|
"prettier/prettier": [
|
|
79
83
|
"error",
|
|
@@ -95,5 +99,14 @@
|
|
|
95
99
|
"quoteProps": "consistent",
|
|
96
100
|
"singleQuote": true,
|
|
97
101
|
"trailingComma": "es5"
|
|
102
|
+
},
|
|
103
|
+
"jest": {
|
|
104
|
+
"testEnvironment": "node",
|
|
105
|
+
"transform": {
|
|
106
|
+
"^.+\\.js$": "babel-jest"
|
|
107
|
+
},
|
|
108
|
+
"transformIgnorePatterns": [
|
|
109
|
+
"node_modules/(?!react-native)"
|
|
110
|
+
]
|
|
98
111
|
}
|
|
99
112
|
}
|