@dashx/react-native 1.1.5 → 1.2.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.
- package/.DS_Store +0 -0
- package/.claude/settings.local.json +18 -1
- package/.gitignore +1 -1
- package/DashXReactNative.podspec +3 -24
- package/README.md +3 -1
- package/__tests__/fallback.test.js +72 -0
- package/__tests__/index.test.js +17 -4
- package/android/build.gradle +27 -1
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/com/dashx/rn/sdk/DashXReactNativeModuleImpl.kt +384 -0
- package/android/src/newarch/java/com/dashx/rn/sdk/DashXReactNativeModule.kt +85 -0
- package/android/src/newarch/java/com/dashx/rn/sdk/DashXReactNativePackage.kt +33 -0
- package/android/src/oldarch/java/com/dashx/rn/sdk/DashXReactNativeModule.kt +106 -0
- package/android/src/oldarch/java/com/dashx/rn/sdk/DashXReactNativePackage.kt +33 -0
- package/index.d.ts +3 -1
- package/index.js +6 -8
- package/ios/DashXNotificationHandler.swift +222 -0
- package/ios/DashXReactNative-Bridging-Header.h +0 -2
- package/ios/DashXReactNative.mm +32 -9
- package/ios/DashXReactNative.swift +26 -18
- package/package.json +11 -2
- package/src/NativeDashXReactNative.ts +42 -0
- package/android/src/main/java/com/dashx/rn/sdk/DashXReactNativeModule.kt +0 -231
- package/android/src/main/java/com/dashx/rn/sdk/DashXReactNativePackage.kt +0 -18
- package/ios/DashXRCTAppDelegate.h +0 -3
- package/ios/DashXRCTAppDelegate.swift +0 -266
- package/ios/DashXReactNative.h +0 -1
|
@@ -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
|
package/ios/DashXReactNative.h
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
#import "DashXRCTAppDelegate.h"
|