@dashx/react-native 1.1.2 → 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 +208 -101
- package/__tests__/index.test.js +363 -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.gradle +1 -1
- package/babel.config.js +1 -1
- package/index.d.ts +70 -0
- package/index.js +63 -6
- package/ios/.DS_Store +0 -0
- package/ios/DashXRCTAppDelegate.swift +75 -47
- package/ios/DashXReactNative-Bridging-Header.h +2 -0
- package/ios/DashXReactNative.h +1 -0
- package/ios/DashXReactNative.mm +12 -0
- package/ios/DashXReactNative.swift +105 -27
- package/package.json +16 -3
package/.DS_Store
ADDED
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(xcodebuild -scheme DashX -destination 'generic/platform=iOS')",
|
|
5
|
+
"Bash(grep -v \"^$\")",
|
|
6
|
+
"Bash(find /Users/gulshan/Work/dashx-demo-ios -name *.entitlements)",
|
|
7
|
+
"Bash(wc -l /Users/gulshan/Work/dashx-ios/Sources/DashX/*.swift)",
|
|
8
|
+
"Bash(swift build:*)",
|
|
9
|
+
"Bash(xcodebuild -scheme DashX -destination 'generic/platform=iOS' build)",
|
|
10
|
+
"Bash(./gradlew :dashx:compileDebugKotlin)",
|
|
11
|
+
"Bash(./gradlew :dashx:compileDebugKotlin --info)"
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main,develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main,develop]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint-and-test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Setup Node.js
|
|
16
|
+
uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: 18
|
|
19
|
+
cache: yarn
|
|
20
|
+
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: yarn install --frozen-lockfile
|
|
23
|
+
|
|
24
|
+
- name: Lint
|
|
25
|
+
run: yarn lint
|
|
26
|
+
|
|
27
|
+
- name: Test
|
|
28
|
+
run: yarn test
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Contributing to @dashx/react-native
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
|
|
5
|
+
- Node.js >= 16
|
|
6
|
+
- Yarn
|
|
7
|
+
- Xcode (for iOS)
|
|
8
|
+
- Android Studio with JDK 17 (for Android)
|
|
9
|
+
- CocoaPods (`gem install cocoapods`)
|
|
10
|
+
|
|
11
|
+
## Getting Started
|
|
12
|
+
|
|
13
|
+
1. Clone the repository:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
git clone https://github.com/dashxhq/dashx-react-native.git
|
|
17
|
+
cd dashx-react-native
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
2. Install dependencies:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
yarn install
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
3. Run tests:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
yarn test
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
4. Run lint:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
yarn lint
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Building the SDK Locally
|
|
39
|
+
|
|
40
|
+
### Android
|
|
41
|
+
|
|
42
|
+
The Android bridge lives in `android/` and is a Gradle library module that is built as part of a React Native app — it cannot be built standalone because it depends on the React Native Gradle plugin and Android SDK provided by the host app.
|
|
43
|
+
|
|
44
|
+
To build and test locally, use a React Native demo app (e.g. `dashx-demo-react-native`):
|
|
45
|
+
|
|
46
|
+
1. In the demo app's `package.json`, point to your local SDK checkout:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@dashx/react-native": "file:../dashx-react-native"
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
2. Install and build:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
cd dashx-demo-react-native
|
|
58
|
+
yarn install
|
|
59
|
+
cd android
|
|
60
|
+
./gradlew assembleDebug
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
3. **To test with a local `dashx-android` SDK build**, publish it to local Maven and add `mavenLocal()` to the demo app's `android/build.gradle` repositories:
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
# In dashx-android:
|
|
67
|
+
./gradlew publishToMavenLocal
|
|
68
|
+
|
|
69
|
+
# In dashx-react-native/android/build.gradle, add:
|
|
70
|
+
repositories {
|
|
71
|
+
mavenLocal()
|
|
72
|
+
// ...
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### iOS
|
|
77
|
+
|
|
78
|
+
The iOS bridge lives in `ios/` and is distributed as a CocoaPod (`DashXReactNative.podspec`). Like Android, it is built as part of a React Native app's Xcode workspace.
|
|
79
|
+
|
|
80
|
+
To build and test locally, use a React Native demo app (e.g. `dashx-demo-react-native`):
|
|
81
|
+
|
|
82
|
+
1. In the demo app's `package.json`, point to your local SDK checkout:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
"dependencies": {
|
|
86
|
+
"@dashx/react-native": "file:../dashx-react-native"
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
2. Install dependencies and pods:
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
cd dashx-demo-react-native
|
|
94
|
+
yarn install
|
|
95
|
+
cd ios
|
|
96
|
+
pod install
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
3. Build from Xcode by opening the `.xcworkspace`, or from the command line:
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
xcodebuild -workspace ios/DashXDemoReactNative.xcworkspace \
|
|
103
|
+
-scheme DashXDemoReactNative \
|
|
104
|
+
-destination 'generic/platform=iOS Simulator' \
|
|
105
|
+
build
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
4. **To test with a local `dashx-ios` SDK build**, add a path override in the demo app's `Podfile`:
|
|
109
|
+
|
|
110
|
+
```ruby
|
|
111
|
+
pod 'DashX', :path => '../../dashx-ios'
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Then re-run `pod install`.
|
|
115
|
+
|
|
116
|
+
## Project Structure
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
dashx-react-native/
|
|
120
|
+
index.js # JS bridge — public API surface
|
|
121
|
+
index.d.ts # TypeScript type definitions
|
|
122
|
+
android/
|
|
123
|
+
src/main/java/com/dashx/rn/sdk/
|
|
124
|
+
DashXReactNativeModule.kt # Android native module
|
|
125
|
+
DashXReactNativePackage.kt # Package registration
|
|
126
|
+
DashXReactNativeFirebaseMessagingService.kt # FCM service
|
|
127
|
+
util/ # Bridge conversion utilities
|
|
128
|
+
build.gradle # Android build config
|
|
129
|
+
ios/
|
|
130
|
+
DashXReactNative.swift # iOS native module
|
|
131
|
+
DashXReactNative.mm # Obj-C++ bridge exports
|
|
132
|
+
DashXEventEmitter.swift # Event emitter for push notifications
|
|
133
|
+
DashXRCTAppDelegate.swift # AppDelegate with Firebase/push handling
|
|
134
|
+
DashXReactNative.podspec # CocoaPods spec
|
|
135
|
+
__tests__/ # Jest tests
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Running Tests
|
|
139
|
+
|
|
140
|
+
```sh
|
|
141
|
+
yarn test
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Tests mock the React Native native modules and verify the JS bridge layer: input validation, native method delegation, promise handling, and event listener registration.
|
|
145
|
+
|
|
146
|
+
## Publishing
|
|
147
|
+
|
|
148
|
+
Use `yarn publish` to bump the version and release to npm:
|
|
149
|
+
|
|
150
|
+
```sh
|
|
151
|
+
yarn publish
|
|
152
|
+
git push origin main
|
|
153
|
+
```
|
package/DashXReactNative.podspec
CHANGED
|
@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
|
|
|
11
11
|
s.license = package["license"]
|
|
12
12
|
s.authors = package["author"]
|
|
13
13
|
|
|
14
|
-
s.platforms = { :ios => "
|
|
14
|
+
s.platforms = { :ios => "13.0" }
|
|
15
15
|
s.source = { :git => "https://github.com/dashxhq/dashx-react-native.git", :tag => "#{s.version}" }
|
|
16
16
|
|
|
17
17
|
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
@@ -40,6 +40,10 @@ Pod::Spec.new do |s|
|
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
s.dependency "DashX", "1.0.19"
|
|
44
43
|
s.dependency "React-RCTAppDelegate"
|
|
44
|
+
# DashX iOS SDK — consumers must provide the source in their Podfile:
|
|
45
|
+
# pod 'DashX', :git => 'https://github.com/dashxhq/dashx-ios.git', :tag => '1.1.4'
|
|
46
|
+
# For local development:
|
|
47
|
+
# pod 'DashX', :path => '../dashx-ios'
|
|
48
|
+
s.dependency "DashX", "~> 1.1.4"
|
|
45
49
|
end
|
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ _DashX SDK for React Native_
|
|
|
30
30
|
|
|
31
31
|
| Platform | Minimum Version |
|
|
32
32
|
|----------|----------------|
|
|
33
|
-
| iOS |
|
|
33
|
+
| iOS | 13.0+ |
|
|
34
34
|
| Android | SDK 26 (Android 8.0)+ |
|
|
35
35
|
| React Native | 0.71+ |
|
|
36
36
|
| Node.js | 16.0+ |
|
|
@@ -76,33 +76,67 @@ apply plugin: 'com.google.gms.google-services'
|
|
|
76
76
|
|
|
77
77
|
### Setup for iOS
|
|
78
78
|
|
|
79
|
-
1
|
|
79
|
+
#### Step 1: Add pods to your Podfile
|
|
80
|
+
|
|
81
|
+
The DashX iOS SDK is not published to CocoaPods trunk. Add it directly from GitHub along with the Firebase pods required for FCM push notifications.
|
|
82
|
+
|
|
83
|
+
Add `use_modular_headers!` at the top of your `ios/Podfile`, then add the pods inside the target block:
|
|
80
84
|
|
|
81
85
|
```ruby
|
|
82
|
-
|
|
86
|
+
use_modular_headers!
|
|
87
|
+
|
|
88
|
+
target 'YourApp' do
|
|
89
|
+
# ... other pods
|
|
90
|
+
|
|
91
|
+
pod 'DashX', :git => 'https://github.com/dashxhq/dashx-ios.git', :tag => '1.1.4'
|
|
92
|
+
pod 'FirebaseCore'
|
|
93
|
+
pod 'FirebaseMessaging'
|
|
94
|
+
|
|
95
|
+
use_react_native!(...)
|
|
96
|
+
end
|
|
83
97
|
```
|
|
84
98
|
|
|
85
|
-
|
|
99
|
+
Then run:
|
|
86
100
|
|
|
87
101
|
```sh
|
|
88
102
|
cd ios && pod install
|
|
89
103
|
```
|
|
90
104
|
|
|
91
|
-
|
|
105
|
+
#### Step 2: Add GoogleService-Info.plist
|
|
106
|
+
|
|
107
|
+
1. Add your iOS app on [Firebase Console](https://console.firebase.google.com/): **Project Overview > Add App > iOS**
|
|
108
|
+
2. Download `GoogleService-Info.plist` and add it to your Xcode project (right-click project root > **Add Files to "YourApp"**, ensure **Copy items if needed** is checked)
|
|
92
109
|
|
|
93
|
-
|
|
110
|
+
#### Step 3: Enable Push Notifications capability
|
|
94
111
|
|
|
95
|
-
|
|
112
|
+
In Xcode, select your app target > **Signing & Capabilities** > **+ Capability** > add **Push Notifications**.
|
|
96
113
|
|
|
97
|
-
|
|
114
|
+
#### Step 4: Configure your AppDelegate
|
|
115
|
+
|
|
116
|
+
The SDK ships `DashXRCTAppDelegate` which handles permission requests, notification display, and universal link forwarding. Subclass it in your `AppDelegate.swift` and configure Firebase directly:
|
|
98
117
|
|
|
99
118
|
```swift
|
|
100
119
|
import DashXReactNative
|
|
120
|
+
import ReactAppDependencyProvider
|
|
121
|
+
import FirebaseCore
|
|
122
|
+
import FirebaseMessaging
|
|
123
|
+
import DashX
|
|
124
|
+
import UserNotifications
|
|
101
125
|
|
|
102
126
|
@main
|
|
103
127
|
class AppDelegate: DashXRCTAppDelegate {
|
|
104
|
-
override
|
|
105
|
-
|
|
128
|
+
override var moduleName: String { "YourAppName" }
|
|
129
|
+
|
|
130
|
+
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
|
131
|
+
self.dependencyProvider = RCTAppDependencyProvider()
|
|
132
|
+
FirebaseApp.configure()
|
|
133
|
+
Messaging.messaging().delegate = self
|
|
134
|
+
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Forward the APNS token to Firebase so it can exchange it for an FCM token
|
|
138
|
+
override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
|
139
|
+
Messaging.messaging().setAPNSToken(deviceToken, type: .unknown)
|
|
106
140
|
}
|
|
107
141
|
|
|
108
142
|
override func bundleURL() -> URL? {
|
|
@@ -112,47 +146,63 @@ class AppDelegate: DashXRCTAppDelegate {
|
|
|
112
146
|
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
|
|
113
147
|
#endif
|
|
114
148
|
}
|
|
149
|
+
}
|
|
115
150
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// Called when a notification arrives while the app is in the foreground
|
|
122
|
-
override func notificationDeliveredInForeground(message: [AnyHashable: Any]) -> UNNotificationPresentationOptions {
|
|
123
|
-
return [.banner, .sound]
|
|
151
|
+
// Receive the FCM token and pass it to DashX
|
|
152
|
+
extension AppDelegate: MessagingDelegate {
|
|
153
|
+
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
|
|
154
|
+
guard let token = fcmToken else { return }
|
|
155
|
+
DashX.setFCMToken(to: token)
|
|
124
156
|
}
|
|
125
157
|
}
|
|
126
158
|
```
|
|
127
159
|
|
|
128
|
-
|
|
160
|
+
`DashXRCTAppDelegate` handles the rest automatically:
|
|
161
|
+
- Requests notification permission on launch
|
|
162
|
+
- Displays notifications (banner + sound by default, even while app is in the foreground)
|
|
163
|
+
- Tracks delivery, clicks, and dismissals
|
|
164
|
+
- Forwards universal links to the JS `onLinkReceived` listener
|
|
165
|
+
|
|
166
|
+
**Override points** (all optional):
|
|
129
167
|
|
|
130
|
-
|
|
168
|
+
```swift
|
|
169
|
+
/// Control foreground notification presentation (default: [.banner, .sound])
|
|
170
|
+
override func notificationDeliveredInForeground(message: [AnyHashable: Any]) -> UNNotificationPresentationOptions {
|
|
171
|
+
return [.banner, .sound, .badge]
|
|
172
|
+
}
|
|
131
173
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
174
|
+
// Called when the user taps a notification or one of its action buttons
|
|
175
|
+
override func notificationClicked(message: [AnyHashable: Any], actionIdentifier: String) {
|
|
176
|
+
// custom tap handling
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Called when a universal/deep link arrives
|
|
180
|
+
override func handleLink(url: URL) {
|
|
181
|
+
// custom link handling
|
|
182
|
+
}
|
|
135
183
|
```
|
|
136
184
|
|
|
137
|
-
|
|
185
|
+
#### Step 5: Subscribe in JavaScript
|
|
138
186
|
|
|
139
|
-
|
|
140
|
-
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
|
|
141
|
-
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
|
|
142
|
-
[[UNUserNotificationCenter currentNotificationCenter]
|
|
143
|
-
requestAuthorizationWithOptions:authOptions
|
|
144
|
-
completionHandler:^(BOOL granted, NSError * _Nullable error) {
|
|
145
|
-
}];
|
|
187
|
+
Call `DashX.subscribe()` at app startup so the SDK registers the device as soon as the FCM token is available:
|
|
146
188
|
|
|
147
|
-
|
|
189
|
+
```js
|
|
190
|
+
import { useEffect } from 'react';
|
|
191
|
+
import DashX from '@dashx/react-native';
|
|
148
192
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
193
|
+
DashX.configure({ publicKey: 'your-public-key' });
|
|
194
|
+
|
|
195
|
+
export default function App() {
|
|
196
|
+
useEffect(() => {
|
|
197
|
+
DashX.subscribe();
|
|
198
|
+
}, []);
|
|
152
199
|
|
|
153
|
-
|
|
200
|
+
// ...
|
|
201
|
+
}
|
|
154
202
|
```
|
|
155
203
|
|
|
204
|
+
> **Without Firebase:** If you are not using FCM, omit the Firebase pods and the Firebase-related `AppDelegate` code. The SDK will still handle APNS permission requests and notification display via `DashXRCTAppDelegate`.
|
|
205
|
+
|
|
156
206
|
## Usage
|
|
157
207
|
|
|
158
208
|
```js
|
|
@@ -229,10 +279,10 @@ DashX.screen('HomeScreen', {
|
|
|
229
279
|
|
|
230
280
|
### Fetch a record
|
|
231
281
|
|
|
232
|
-
Fetch a single record by URN (e.g. `"article/
|
|
282
|
+
Fetch a single record by URN (e.g. `"article/uuid"`). The URN must use the full UUID form of the record ID.
|
|
233
283
|
|
|
234
284
|
```js
|
|
235
|
-
const record = await DashX.fetchRecord('article/
|
|
285
|
+
const record = await DashX.fetchRecord('article/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', {
|
|
236
286
|
preview: false,
|
|
237
287
|
language: 'en',
|
|
238
288
|
// fields, include, exclude as arrays of objects if needed
|
|
@@ -249,13 +299,12 @@ const record = await DashX.fetchRecord('article/123', {
|
|
|
249
299
|
|
|
250
300
|
### Search records
|
|
251
301
|
|
|
252
|
-
Search records by resource with optional filter, order, limit, and other options (matches [dashx-android](https://github.com/dashxhq/dashx-android) `searchRecords`). **Android only**; on iOS the promise rejects until the native SDK supports it.
|
|
253
|
-
|
|
254
302
|
```js
|
|
255
303
|
const records = await DashX.searchRecords('article', {
|
|
256
304
|
filter: { status: 'published' },
|
|
257
305
|
order: [{ field: 'createdAt', direction: 'desc' }],
|
|
258
306
|
limit: 10,
|
|
307
|
+
page: 1,
|
|
259
308
|
preview: false,
|
|
260
309
|
language: 'en',
|
|
261
310
|
});
|
|
@@ -266,6 +315,7 @@ const records = await DashX.searchRecords('article', {
|
|
|
266
315
|
| `filter` | `object` | Filter criteria |
|
|
267
316
|
| `order` | `object[]` | Sort order (e.g. `[{ field, direction }]`) |
|
|
268
317
|
| `limit` | `number` | Max records to return |
|
|
318
|
+
| `page` | `number` | Page number for pagination |
|
|
269
319
|
| `preview` | `boolean` | Preview/draft content |
|
|
270
320
|
| `language` | `string` | Content language |
|
|
271
321
|
| `fields` | `object[]` | Fields to return |
|
|
@@ -286,6 +336,31 @@ Unsubscribe:
|
|
|
286
336
|
DashX.unsubscribe();
|
|
287
337
|
```
|
|
288
338
|
|
|
339
|
+
### Request notification permission (iOS)
|
|
340
|
+
|
|
341
|
+
Prompt the user for push notification permission. Returns a `NotificationPermissionStatus` integer matching `UNAuthorizationStatus`:
|
|
342
|
+
|
|
343
|
+
| Value | Meaning |
|
|
344
|
+
|-------|---------|
|
|
345
|
+
| `0` | Not determined |
|
|
346
|
+
| `1` | Denied |
|
|
347
|
+
| `2` | Authorized |
|
|
348
|
+
| `3` | Provisional |
|
|
349
|
+
| `4` | Ephemeral |
|
|
350
|
+
|
|
351
|
+
```js
|
|
352
|
+
const status = await DashX.requestNotificationPermission();
|
|
353
|
+
if (status === 2) {
|
|
354
|
+
DashX.subscribe();
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
To check the current status without prompting the user:
|
|
359
|
+
|
|
360
|
+
```js
|
|
361
|
+
const status = await DashX.getNotificationPermissionStatus();
|
|
362
|
+
```
|
|
363
|
+
|
|
289
364
|
### Listen for incoming messages
|
|
290
365
|
|
|
291
366
|
Register a listener to handle push notifications when they arrive:
|
|
@@ -302,13 +377,26 @@ useEffect(() => {
|
|
|
302
377
|
}, []);
|
|
303
378
|
```
|
|
304
379
|
|
|
380
|
+
### Listen for deep links / universal links (iOS)
|
|
381
|
+
|
|
382
|
+
Register a listener that fires when the SDK receives a universal link. On the native side, `DashXRCTAppDelegate` forwards links via `DashX.handleUserActivity` automatically.
|
|
383
|
+
|
|
384
|
+
```js
|
|
385
|
+
useEffect(() => {
|
|
386
|
+
const subscription = DashX.onLinkReceived((url) => {
|
|
387
|
+
console.log('Link received:', url);
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
return () => subscription.remove();
|
|
391
|
+
}, []);
|
|
392
|
+
```
|
|
393
|
+
|
|
305
394
|
### Notification preferences
|
|
306
395
|
|
|
307
396
|
Fetch the user's stored notification preferences:
|
|
308
397
|
|
|
309
398
|
```js
|
|
310
399
|
const preferences = await DashX.fetchStoredPreferences();
|
|
311
|
-
console.log(preferences);
|
|
312
400
|
```
|
|
313
401
|
|
|
314
402
|
Save updated preferences:
|
|
@@ -320,84 +408,103 @@ await DashX.saveStoredPreferences({
|
|
|
320
408
|
});
|
|
321
409
|
```
|
|
322
410
|
|
|
323
|
-
###
|
|
411
|
+
### Upload an asset (iOS)
|
|
324
412
|
|
|
325
|
-
|
|
413
|
+
Upload a local file to DashX and associate it with a resource and attribute:
|
|
326
414
|
|
|
327
415
|
```js
|
|
328
|
-
|
|
416
|
+
const response = await DashX.uploadAsset(
|
|
417
|
+
'/path/to/local/file.jpg',
|
|
418
|
+
'user', // resource name
|
|
419
|
+
'avatar' // attribute name
|
|
420
|
+
);
|
|
421
|
+
// response: { status, data: { asset: { status, url, playbackIds } } }
|
|
329
422
|
```
|
|
330
423
|
|
|
331
|
-
###
|
|
424
|
+
### Fetch an asset (iOS)
|
|
332
425
|
|
|
333
|
-
|
|
426
|
+
Retrieve the status and URL of a previously uploaded asset by its ID:
|
|
334
427
|
|
|
335
428
|
```js
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
import DashX from '@dashx/react-native';
|
|
429
|
+
const asset = await DashX.fetchAsset('asset-id');
|
|
430
|
+
// asset: { status, data: { asset: { status, url, playbackIds } } }
|
|
431
|
+
```
|
|
340
432
|
|
|
341
|
-
|
|
342
|
-
DashX.configure({ publicKey: 'your-public-key' });
|
|
343
|
-
DashX.subscribe();
|
|
433
|
+
### Lifecycle tracking (iOS)
|
|
344
434
|
|
|
345
|
-
|
|
346
|
-
const handleLogin = () => {
|
|
347
|
-
DashX.setIdentity('user-123', 'auth-token');
|
|
348
|
-
DashX.identify({
|
|
349
|
-
firstName: 'Jane',
|
|
350
|
-
lastName: 'Doe',
|
|
351
|
-
email: 'jane@example.com',
|
|
352
|
-
});
|
|
353
|
-
};
|
|
354
|
-
|
|
355
|
-
const handleTrack = () => {
|
|
356
|
-
DashX.track('Button Pressed', { screen: 'Home' });
|
|
357
|
-
};
|
|
358
|
-
|
|
359
|
-
const handleLogout = () => {
|
|
360
|
-
DashX.unsubscribe();
|
|
361
|
-
DashX.reset();
|
|
362
|
-
};
|
|
363
|
-
|
|
364
|
-
return (
|
|
365
|
-
<View style={styles.container}>
|
|
366
|
-
<Text style={styles.title}>DashX React Native Demo</Text>
|
|
367
|
-
<Button title="Login" onPress={handleLogin} />
|
|
368
|
-
<Button title="Track Event" onPress={handleTrack} />
|
|
369
|
-
<Button title="Logout" onPress={handleLogout} />
|
|
370
|
-
</View>
|
|
371
|
-
);
|
|
372
|
-
}
|
|
435
|
+
Enable automatic app lifecycle event tracking (app opened, backgrounded, etc.):
|
|
373
436
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
437
|
+
```js
|
|
438
|
+
DashX.enableLifecycleTracking(); // no-op on Android
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### Ad tracking / ATT (iOS)
|
|
442
|
+
|
|
443
|
+
Request App Tracking Transparency permission and enable IDFA tracking:
|
|
444
|
+
|
|
445
|
+
```js
|
|
446
|
+
DashX.enableAdTracking(); // no-op on Android
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
Make sure `NSUserTrackingUsageDescription` is set in your `Info.plist`.
|
|
450
|
+
|
|
451
|
+
### Logging
|
|
452
|
+
|
|
453
|
+
Set the SDK log level for debugging:
|
|
454
|
+
|
|
455
|
+
```js
|
|
456
|
+
DashX.setLogLevel(1); // 0 = off, 1 = errors, 2 = debug
|
|
378
457
|
```
|
|
379
458
|
|
|
380
459
|
## API Reference
|
|
381
460
|
|
|
382
|
-
| Method | Signature | Returns | Description |
|
|
383
|
-
|
|
384
|
-
| `configure` | `(options: object)` | `void` | Initialize the SDK with your public key |
|
|
385
|
-
| `identify` | `(options: object)` | `void` | Identify the current user with traits |
|
|
386
|
-
| `setIdentity` | `(uid: string, token: string)` | `void` | Set user identity with UID and auth token |
|
|
387
|
-
| `reset` | `()` | `void` | Clear the current user identity |
|
|
388
|
-
| `track` | `(event: string, data?: object)` | `void` | Track a named event with optional data |
|
|
389
|
-
| `screen` | `(screenName: string, data?: object)` | `void` | Track a screen view
|
|
390
|
-
| `fetchRecord` | `(urn: string, options?: object)` | `Promise<object>` | Fetch a single record by URN (
|
|
391
|
-
| `searchRecords` | `(resource: string, options?: object)` | `Promise<object[]>` | Search records
|
|
392
|
-
| `subscribe` | `()` | `void` | Subscribe device for push notifications |
|
|
393
|
-
| `unsubscribe` | `()` | `void` | Unsubscribe device from push notifications |
|
|
394
|
-
| `fetchStoredPreferences` | `()` | `Promise<object>` | Fetch stored notification preferences |
|
|
395
|
-
| `saveStoredPreferences` | `(data: object)` | `Promise<object>` | Save notification preferences |
|
|
396
|
-
| `setLogLevel` | `(level: number)` | `void` | Set SDK log verbosity |
|
|
397
|
-
| `onMessageReceived` | `(callback: function)` | `EmitterSubscription` | Listen for incoming push notifications |
|
|
461
|
+
| Method | Signature | Platforms | Returns | Description |
|
|
462
|
+
|--------|-----------|-----------|---------|-------------|
|
|
463
|
+
| `configure` | `(options: object)` | iOS, Android | `void` | Initialize the SDK with your public key |
|
|
464
|
+
| `identify` | `(options: object)` | iOS, Android | `void` | Identify the current user with traits |
|
|
465
|
+
| `setIdentity` | `(uid: string, token: string)` | iOS, Android | `void` | Set user identity with UID and auth token |
|
|
466
|
+
| `reset` | `()` | iOS, Android | `void` | Clear the current user identity |
|
|
467
|
+
| `track` | `(event: string, data?: object)` | iOS, Android | `void` | Track a named event with optional data |
|
|
468
|
+
| `screen` | `(screenName: string, data?: object)` | iOS, Android | `void` | Track a screen view |
|
|
469
|
+
| `fetchRecord` | `(urn: string, options?: object)` | iOS, Android | `Promise<object>` | Fetch a single record by URN (`"resource/uuid"`) |
|
|
470
|
+
| `searchRecords` | `(resource: string, options?: object)` | iOS, Android | `Promise<object[]>` | Search records with filter, order, limit, page, etc. |
|
|
471
|
+
| `subscribe` | `()` | iOS, Android | `void` | Subscribe device for push notifications |
|
|
472
|
+
| `unsubscribe` | `()` | iOS, Android | `void` | Unsubscribe device from push notifications |
|
|
473
|
+
| `fetchStoredPreferences` | `()` | iOS, Android | `Promise<object>` | Fetch stored notification preferences |
|
|
474
|
+
| `saveStoredPreferences` | `(data: object)` | iOS, Android | `Promise<object>` | Save notification preferences |
|
|
475
|
+
| `setLogLevel` | `(level: number)` | iOS, Android | `void` | Set SDK log verbosity (0=off, 1=errors, 2=debug) |
|
|
476
|
+
| `onMessageReceived` | `(callback: function)` | iOS, Android | `EmitterSubscription` | Listen for incoming push notifications |
|
|
477
|
+
| `requestNotificationPermission` | `()` | iOS | `Promise<number>` | Prompt for push permission; resolves with `UNAuthorizationStatus` (0-4) |
|
|
478
|
+
| `getNotificationPermissionStatus` | `()` | iOS | `Promise<number>` | Get current push permission status without prompting |
|
|
479
|
+
| `onLinkReceived` | `(callback: function)` | iOS | `EmitterSubscription` | Listen for universal/deep link events |
|
|
480
|
+
| `uploadAsset` | `(filePath: string, resource: string, attribute: string)` | iOS | `Promise<AssetResponse>` | Upload a local file and associate it with a resource attribute |
|
|
481
|
+
| `fetchAsset` | `(assetId: string)` | iOS | `Promise<AssetResponse>` | Fetch status and URL of an uploaded asset |
|
|
482
|
+
| `enableLifecycleTracking` | `()` | iOS | `void` | Enable automatic app lifecycle event tracking |
|
|
483
|
+
| `enableAdTracking` | `()` | iOS | `void` | Request ATT permission and enable IDFA tracking |
|
|
398
484
|
|
|
399
485
|
For detailed usage and advanced features, refer to the [DashX documentation](https://docs.dashx.com/developer).
|
|
400
486
|
|
|
487
|
+
### Error Codes
|
|
488
|
+
|
|
489
|
+
Promise rejections from native methods use a consistent error code across both platforms:
|
|
490
|
+
|
|
491
|
+
| Code | Description |
|
|
492
|
+
|------|-------------|
|
|
493
|
+
| `EUNSPECIFIED` | An unspecified error occurred |
|
|
494
|
+
|
|
495
|
+
The error code is available on the `code` property of the rejected error:
|
|
496
|
+
|
|
497
|
+
```js
|
|
498
|
+
try {
|
|
499
|
+
await DashX.fetchRecord('article/123');
|
|
500
|
+
} catch (error) {
|
|
501
|
+
console.log(error.code); // "EUNSPECIFIED"
|
|
502
|
+
console.log(error.message); // human-readable description
|
|
503
|
+
}
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
A `DashXErrorCode` enum is exported from the TypeScript definitions for type-safe comparisons.
|
|
507
|
+
|
|
401
508
|
## Contributing
|
|
402
509
|
|
|
403
510
|
Please follow [these steps](https://github.com/dashxhq/dashx-js/tree/master/examples/react-native#setting-up-development-environment) to set up the development environment.
|