react-native-insider 7.0.4 → 7.0.5
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/.git-hooks/README.md +22 -1
- package/.git-hooks/pre-push +25 -0
- package/README.md +672 -72
- package/RNInsider.podspec +4 -4
- package/android/build.gradle +2 -2
- package/android/src/main/java/com/useinsider/react/RNInsiderModule.java +37 -0
- package/ios/RNInsider/RNInsider.m +41 -0
- package/package.json +1 -1
- package/src/InsiderProduct.d.ts +1 -0
- package/src/InsiderProduct.js +15 -0
- package/src/InsiderUser.d.ts +1 -0
- package/src/InsiderUser.js +14 -0
package/.git-hooks/README.md
CHANGED
|
@@ -23,14 +23,35 @@ Ensures commit messages follow the Conventional Commits specification, with cust
|
|
|
23
23
|
- Max 120 characters (hard limit)
|
|
24
24
|
- Warning if over 50 or 72 characters.
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
|
|
27
|
+
### 2. `pre-push`
|
|
28
|
+
|
|
29
|
+
Prevents developers from pushing to any branch that ends with *-nh if any Gradle file in the project contains Huawei-related dependencies or repositories.
|
|
30
|
+
|
|
31
|
+
- **What it checks for**:
|
|
32
|
+
- com.huawei.hms (HMS SDK)
|
|
33
|
+
- com.huawei.agconnect (AG Connect SDK)
|
|
34
|
+
- developer.huawei.com/repo (Huawei Maven repository)
|
|
35
|
+
|
|
36
|
+
The purpose of this rule is to ensure that non-huawei (-nh) branches remain clean of Huawei dependencies.
|
|
37
|
+
|
|
38
|
+
- **How it works**:
|
|
39
|
+
- Runs only on branches whose names end with `-nh`.
|
|
40
|
+
- Lists all tracked Gradle files (`*.gradle`, `*.gradle.kts`) in the repository once and scans their contents for the above patterns.
|
|
41
|
+
- If any match is found, the push is blocked with a short message.
|
|
42
|
+
|
|
43
|
+
You can temporarily skip the check with `git push --no-verify` (not recommended).
|
|
27
44
|
|
|
28
45
|
## 🔧 Installation
|
|
29
46
|
|
|
30
47
|
### 1. Copy Hooks to `.git/hooks/`
|
|
31
48
|
|
|
32
49
|
Run the following commands under project's directory:
|
|
50
|
+
|
|
33
51
|
```bash
|
|
34
52
|
cp .git-hooks/commit-msg .git/hooks/commit-msg
|
|
35
53
|
chmod +x .git/hooks/commit-msg
|
|
54
|
+
|
|
55
|
+
cp .git-hooks/pre-push .git/hooks/pre-push
|
|
56
|
+
chmod +x .git/hooks/pre-push
|
|
36
57
|
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")"
|
|
6
|
+
if [ -z "${CURRENT_BRANCH}" ] || [ "${CURRENT_BRANCH}" = "HEAD" ]; then
|
|
7
|
+
exit 0
|
|
8
|
+
fi
|
|
9
|
+
|
|
10
|
+
if [ -z "$(git ls-files -- '*.gradle' '*.gradle.kts' || true)" ]; then
|
|
11
|
+
exit 0
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
if [[ "${CURRENT_BRANCH}" == *-nh ]]; then
|
|
15
|
+
if git ls-files -z -- '*.gradle' '*.gradle.kts' \
|
|
16
|
+
| xargs -0 grep -qiE \
|
|
17
|
+
-e 'com\.huawei\.hms' \
|
|
18
|
+
-e 'com\.huawei\.agconnect' \
|
|
19
|
+
-e '(^|[^A-Za-z0-9_])agconnect([^A-Za-z0-9_]|$)' \
|
|
20
|
+
-e 'developer\.huawei\.com/repo'
|
|
21
|
+
then
|
|
22
|
+
echo "⛔ Error: ${CURRENT_BRANCH} dalını gönderemezsiniz çünkü Huawei referansı Gradle dosyalarında mevcut."
|
|
23
|
+
exit 1
|
|
24
|
+
fi
|
|
25
|
+
fi
|
package/README.md
CHANGED
|
@@ -1,109 +1,709 @@
|
|
|
1
|
+
# React Native Insider SDK
|
|
1
2
|
|
|
2
|
-
|
|
3
|
+
Official React Native SDK for [Insider](https://useinsider.com/) - A single platform for building individualized, cross-channel customer experiences.
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/react-native-insider)
|
|
6
|
+
[](https://useinsider.com)
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
## Features
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
- **User Management** - Comprehensive user profile management with custom attributes
|
|
11
|
+
- **Event Tracking** - Track custom events with flexible parameters
|
|
12
|
+
- **E-commerce** - Product tracking, cart management, purchase events, and wishlist
|
|
13
|
+
- **Smart Recommendations** - AI-powered personalized product recommendations
|
|
14
|
+
- **Message Center** - In-app messaging and notification management
|
|
15
|
+
- **Content Optimizer** - A/B testing and dynamic content optimization
|
|
16
|
+
- **Push Notifications** - Rich push notifications with deep linking support
|
|
17
|
+
- **In-App Messages** - Native in-app messaging with callback handlers
|
|
18
|
+
- **Geofencing** - Location-based targeting and triggers
|
|
19
|
+
- **GDPR Compliance** - Built-in consent management and privacy controls
|
|
20
|
+
- **TypeScript Support** - Full TypeScript definitions included
|
|
9
21
|
|
|
10
|
-
|
|
22
|
+
## Installation
|
|
11
23
|
|
|
12
|
-
|
|
24
|
+
With npm:
|
|
13
25
|
|
|
14
|
-
|
|
26
|
+
```bash
|
|
27
|
+
npm install react-native-insider
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
With yarn:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
yarn add react-native-insider
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### iOS
|
|
15
37
|
|
|
16
|
-
|
|
38
|
+
1. Install CocoaPods dependencies:
|
|
17
39
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
4. Run your project (`Cmd+R`)
|
|
40
|
+
```bash
|
|
41
|
+
cd ios && pod install && cd ..
|
|
42
|
+
```
|
|
22
43
|
|
|
23
|
-
|
|
44
|
+
2. In your Xcode project, enable the following capabilities under **Signing & Capabilities**:
|
|
45
|
+
- **Push Notifications** (if you are using **InsiderMobileAdvancedNotification** SDK)
|
|
46
|
+
- **Location (Always and WhenInUse)** (if you are using **InsiderGeofence** SDK)
|
|
47
|
+
- **Background Modes**: `Remote notifications` and `Location updates`
|
|
24
48
|
|
|
25
|
-
|
|
26
|
-
- Add `import com.useinsider.react.RNInsiderPackage;` to the imports at the top of the file
|
|
27
|
-
- Add `new RNInsiderPackage()` to the list returned by the `getPackages()` method
|
|
28
|
-
2. Append the following lines to `android/settings.gradle`:
|
|
29
|
-
```
|
|
30
|
-
include ':react-native-insider'
|
|
31
|
-
project(':react-native-insider').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-insider/android')
|
|
32
|
-
```
|
|
33
|
-
3. Insert the following lines inside the dependencies block in `android/app/build.gradle`:
|
|
34
|
-
```
|
|
35
|
-
compile project(':react-native-insider')
|
|
36
|
-
```
|
|
49
|
+
3. For rich push notifications, add Notification Service Extension and Notification Content Extension targets to your iOS project. Add the following to your `Podfile`:
|
|
37
50
|
|
|
38
|
-
|
|
51
|
+
```ruby
|
|
52
|
+
target 'YourNotificationService' do
|
|
53
|
+
use_frameworks!
|
|
54
|
+
pod "InsiderMobileAdvancedNotification"
|
|
55
|
+
end
|
|
39
56
|
|
|
40
|
-
|
|
57
|
+
target 'YourNotificationContent' do
|
|
58
|
+
use_frameworks!
|
|
59
|
+
pod "InsiderMobileAdvancedNotification"
|
|
60
|
+
end
|
|
61
|
+
```
|
|
41
62
|
|
|
42
|
-
|
|
63
|
+
### Android Setup
|
|
43
64
|
|
|
44
|
-
|
|
65
|
+
1. Add the Insider Maven repository to your **project-level** `android/build.gradle`:
|
|
45
66
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
67
|
+
```gradle
|
|
68
|
+
allprojects {
|
|
69
|
+
repositories {
|
|
70
|
+
maven { url 'https://mobilesdk.useinsider.com/android' }
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
49
74
|
|
|
50
|
-
|
|
75
|
+
2. Add Google Services to your **project-level** `android/build.gradle`:
|
|
51
76
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
77
|
+
```gradle
|
|
78
|
+
buildscript {
|
|
79
|
+
dependencies {
|
|
80
|
+
classpath 'com.google.gms:google-services:4.4.4'
|
|
81
|
+
}
|
|
58
82
|
}
|
|
83
|
+
```
|
|
59
84
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
85
|
+
3. In your **app-level** `android/app/build.gradle`, add your partner name:
|
|
86
|
+
|
|
87
|
+
```gradle
|
|
88
|
+
android {
|
|
89
|
+
defaultConfig {
|
|
90
|
+
manifestPlaceholders = [partner: 'your_partner_name']
|
|
91
|
+
}
|
|
64
92
|
}
|
|
65
93
|
```
|
|
66
94
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
95
|
+
4. If `android:allowBackup="false"` exists in your `AndroidManifest.xml`, remove it to allow Insider SDK to function properly.
|
|
96
|
+
|
|
97
|
+
## Quick Start
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import React, { useEffect } from 'react';
|
|
101
|
+
import Insider from 'react-native-insider';
|
|
102
|
+
import InsiderCallbackType from 'react-native-insider/src/InsiderCallbackType';
|
|
103
|
+
|
|
104
|
+
function App() {
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
// Initialize the SDK
|
|
107
|
+
Insider.init(
|
|
108
|
+
'your_partner_name',
|
|
109
|
+
'group.com.your.app', // iOS App Group ID
|
|
110
|
+
(type, data) => {
|
|
111
|
+
// Handle SDK callbacks
|
|
112
|
+
switch(type) {
|
|
113
|
+
case InsiderCallbackType.NOTIFICATION_OPEN:
|
|
114
|
+
console.log('Notification opened:', data);
|
|
115
|
+
break;
|
|
116
|
+
case InsiderCallbackType.INAPP_BUTTON_CLICK:
|
|
117
|
+
console.log('In-app button clicked:', data);
|
|
118
|
+
break;
|
|
119
|
+
case InsiderCallbackType.SESSION_STARTED:
|
|
120
|
+
console.log('Session started');
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
// iOS-specific configurations
|
|
127
|
+
Insider.registerWithQuietPermission(false);
|
|
128
|
+
Insider.setActiveForegroundPushView();
|
|
129
|
+
|
|
130
|
+
// Enable data collection
|
|
131
|
+
Insider.enableIDFACollection(true);
|
|
132
|
+
Insider.enableLocationCollection(true);
|
|
133
|
+
|
|
134
|
+
// Start geofencing
|
|
135
|
+
Insider.startTrackingGeofence();
|
|
136
|
+
}, []);
|
|
137
|
+
|
|
138
|
+
return <YourApp />;
|
|
74
139
|
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## API Reference
|
|
75
143
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
144
|
+
### Initialization
|
|
145
|
+
|
|
146
|
+
#### `init(partnerName, appGroup, callback)`
|
|
147
|
+
|
|
148
|
+
Initialize the Insider SDK with your partner name and callback handler.
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
Insider.init(
|
|
152
|
+
'your_partner_name',
|
|
153
|
+
'group.com.your.app', // iOS App Group ID
|
|
154
|
+
(type, data) => {
|
|
155
|
+
// Handle callbacks
|
|
156
|
+
}
|
|
157
|
+
);
|
|
79
158
|
```
|
|
80
159
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
160
|
+
**Parameters:**
|
|
161
|
+
- `partnerName` (string): Your Insider partner name
|
|
162
|
+
- `appGroup` (string): iOS App Group ID (e.g., 'group.com.your.app')
|
|
163
|
+
- `callback` (function): Callback function to handle SDK events
|
|
164
|
+
|
|
165
|
+
#### `initWithCustomEndpoint(partnerName, appGroup, endpoint, callback)`
|
|
166
|
+
|
|
167
|
+
Initialize with a custom API endpoint for enterprise customers.
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
Insider.initWithCustomEndpoint(
|
|
171
|
+
'your_partner_name',
|
|
172
|
+
'group.com.your.app',
|
|
173
|
+
'https://your-custom-endpoint.com',
|
|
174
|
+
(type, data) => {
|
|
175
|
+
// Handle callbacks
|
|
176
|
+
}
|
|
177
|
+
);
|
|
84
178
|
```
|
|
85
179
|
|
|
86
|
-
|
|
180
|
+
### User Management
|
|
181
|
+
|
|
182
|
+
#### Get Current User
|
|
87
183
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
```javascript
|
|
91
|
-
// Import RNInsider to access the SDK methods.
|
|
92
|
-
import RNInsider from 'react-native-insider';
|
|
184
|
+
```typescript
|
|
185
|
+
const user = Insider.getCurrentUser();
|
|
93
186
|
```
|
|
94
187
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
188
|
+
#### User Attributes
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
import InsiderGender from 'react-native-insider/src/InsiderGender';
|
|
192
|
+
|
|
193
|
+
user
|
|
194
|
+
.setName('John')
|
|
195
|
+
.setSurname('Doe')
|
|
196
|
+
.setAge(30)
|
|
197
|
+
.setGender(InsiderGender.Male) // Male: 0, Female: 1, Other: 2
|
|
198
|
+
.setBirthday(new Date('1990-01-01'))
|
|
199
|
+
.setEmail('john.doe@example.com')
|
|
200
|
+
.setPhoneNumber('+1234567890')
|
|
201
|
+
.setLanguage('en')
|
|
202
|
+
.setLocale('en_US');
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
#### Marketing Preferences
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
user
|
|
209
|
+
.setEmailOptin(true)
|
|
210
|
+
.setSMSOptin(true)
|
|
211
|
+
.setPushOptin(true)
|
|
212
|
+
.setWhatsappOptin(true)
|
|
213
|
+
.setLocationOptin(true);
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
#### Custom Attributes
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
user
|
|
220
|
+
.setCustomAttributeWithString('membership_level', 'gold')
|
|
221
|
+
.setCustomAttributeWithInt('loyalty_points', 1500)
|
|
222
|
+
.setCustomAttributeWithDouble('account_balance', 99.99)
|
|
223
|
+
.setCustomAttributeWithBoolean('is_premium', true)
|
|
224
|
+
.setCustomAttributeWithDate('last_purchase', new Date())
|
|
225
|
+
.setCustomAttributeWithArray('interests', ['sports', 'technology']);
|
|
226
|
+
|
|
227
|
+
// Remove a custom attribute
|
|
228
|
+
user.unsetCustomAttribute('membership_level');
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### Login/Logout
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
import InsiderIdentifier from 'react-native-insider/src/InsiderIdentifier';
|
|
235
|
+
|
|
236
|
+
// Login with identifiers
|
|
237
|
+
const identifiers = new InsiderIdentifier()
|
|
238
|
+
.addEmail('user@example.com')
|
|
239
|
+
.addPhoneNumber('+1234567890')
|
|
240
|
+
.addUserID('user123')
|
|
241
|
+
.addCustomIdentifier('custom_key', 'custom_value');
|
|
242
|
+
|
|
243
|
+
user.login(identifiers);
|
|
244
|
+
|
|
245
|
+
// Login with callback to get Insider ID
|
|
246
|
+
user.login(identifiers, (insiderID) => {
|
|
247
|
+
console.log('Insider ID:', insiderID);
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// Logout
|
|
251
|
+
user.logout();
|
|
252
|
+
|
|
253
|
+
// Sign-up confirmation
|
|
254
|
+
Insider.signUpConfirmation();
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Event Tracking
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
// Simple event
|
|
261
|
+
Insider.tagEvent('app_opened').build();
|
|
262
|
+
|
|
263
|
+
// Event with parameters
|
|
264
|
+
Insider.tagEvent('product_viewed')
|
|
265
|
+
.addParameterWithString('product_id', 'SKU123')
|
|
266
|
+
.addParameterWithString('category', 'Electronics')
|
|
267
|
+
.addParameterWithDouble('price', 299.99)
|
|
268
|
+
.addParameterWithInt('quantity', 1)
|
|
269
|
+
.addParameterWithBoolean('in_stock', true)
|
|
270
|
+
.addParameterWithDate('viewed_at', new Date())
|
|
271
|
+
.addParameterWithArray('tags', ['featured', 'sale'])
|
|
272
|
+
.addParameterWithStringArray('colors', ['red', 'blue'])
|
|
273
|
+
.addParameterWithNumericArray('ratings', [4.5, 5.0])
|
|
274
|
+
.build();
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Product & E-commerce
|
|
278
|
+
|
|
279
|
+
#### Create a Product
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
const product = Insider.createNewProduct(
|
|
283
|
+
'product_id', // Product ID
|
|
284
|
+
'Product Name', // Product name
|
|
285
|
+
['Category', 'Subcategory'], // Taxonomy (array)
|
|
286
|
+
'https://example.com/image.jpg', // Image URL
|
|
287
|
+
99.99, // Price
|
|
288
|
+
'USD' // Currency
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
// Add optional attributes
|
|
292
|
+
product
|
|
293
|
+
.setColor('Blue')
|
|
294
|
+
.setSize('M')
|
|
295
|
+
.setBrand('BrandName')
|
|
296
|
+
.setSalePrice(79.99)
|
|
297
|
+
.setStock(100)
|
|
298
|
+
.setQuantity(1)
|
|
299
|
+
.setSku('SKU-123')
|
|
300
|
+
.setVoucherName('SUMMER2024')
|
|
301
|
+
.setVoucherDiscount(20)
|
|
302
|
+
.setPromotionName('Summer Sale')
|
|
303
|
+
.setPromotionDiscount(15)
|
|
304
|
+
.setShippingCost(5.99)
|
|
305
|
+
.setGender('Unisex')
|
|
306
|
+
.setDescription('Product description')
|
|
307
|
+
.setTags(['featured', 'bestseller'])
|
|
308
|
+
.setInStock(true);
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
#### Cart Operations
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
// Add to cart
|
|
315
|
+
Insider.itemAddedToCart(product);
|
|
316
|
+
|
|
317
|
+
// Remove from cart
|
|
318
|
+
Insider.itemRemovedFromCart('product_id');
|
|
319
|
+
|
|
320
|
+
// Clear cart
|
|
321
|
+
Insider.cartCleared();
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
#### Wishlist Operations
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
// Add to wishlist
|
|
328
|
+
Insider.itemAddedToWishlist(product);
|
|
329
|
+
|
|
330
|
+
// Remove from wishlist
|
|
331
|
+
Insider.itemRemovedFromWishlist('product_id');
|
|
332
|
+
|
|
333
|
+
// Clear wishlist
|
|
334
|
+
Insider.wishlistCleared();
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
#### Purchase
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
Insider.itemPurchased('unique_sale_id_12345', product);
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Page Visits
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
// Home page
|
|
347
|
+
Insider.visitHomePage();
|
|
348
|
+
|
|
349
|
+
// Listing/Category page
|
|
350
|
+
Insider.visitListingPage(['Category', 'Subcategory']);
|
|
351
|
+
|
|
352
|
+
// Product detail page
|
|
353
|
+
Insider.visitProductDetailPage(product);
|
|
354
|
+
|
|
355
|
+
// Cart page with products
|
|
356
|
+
Insider.visitCartPage([product1, product2]);
|
|
357
|
+
|
|
358
|
+
// Wishlist page
|
|
359
|
+
Insider.visitWishlistPage([product1, product2]);
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Smart Recommendations
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
// Basic recommendation
|
|
366
|
+
Insider.getSmartRecommendation(
|
|
367
|
+
12345, // Recommendation ID
|
|
368
|
+
'en_US', // Locale
|
|
369
|
+
'USD', // Currency
|
|
370
|
+
(recommendation) => {
|
|
371
|
+
console.log('Recommendations:', recommendation);
|
|
372
|
+
}
|
|
373
|
+
);
|
|
374
|
+
|
|
375
|
+
// Recommendation with product context
|
|
376
|
+
Insider.getSmartRecommendationWithProduct(
|
|
377
|
+
product, // Current product
|
|
378
|
+
12345, // Recommendation ID
|
|
379
|
+
'en_US', // Locale
|
|
380
|
+
(recommendation) => {
|
|
381
|
+
console.log('Related products:', recommendation);
|
|
382
|
+
}
|
|
383
|
+
);
|
|
384
|
+
|
|
385
|
+
// Recommendation with product IDs
|
|
386
|
+
Insider.getSmartRecommendationWithProductIDs(
|
|
387
|
+
['prod1', 'prod2'], // Product IDs array
|
|
388
|
+
12345, // Recommendation ID
|
|
389
|
+
'en_US', // Locale
|
|
390
|
+
'USD', // Currency
|
|
391
|
+
(recommendation) => {
|
|
392
|
+
console.log('Recommendations:', recommendation);
|
|
393
|
+
}
|
|
394
|
+
);
|
|
395
|
+
|
|
396
|
+
// Track recommendation click
|
|
397
|
+
Insider.clickSmartRecommendationProduct(12345, product);
|
|
100
398
|
```
|
|
399
|
+
|
|
400
|
+
### Message Center
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
Insider.getMessageCenterData(
|
|
404
|
+
20, // Limit
|
|
405
|
+
new Date('2024-01-01'), // Start date
|
|
406
|
+
new Date(), // End date
|
|
407
|
+
(messages) => {
|
|
408
|
+
console.log('Messages:', messages);
|
|
409
|
+
}
|
|
410
|
+
);
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Content Optimizer
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
import ContentOptimizerDataType from 'react-native-insider/src/ContentOptimizerDataType';
|
|
417
|
+
|
|
418
|
+
// Get string content
|
|
419
|
+
Insider.getContentStringWithName(
|
|
420
|
+
'variable_name',
|
|
421
|
+
'default_value',
|
|
422
|
+
ContentOptimizerDataType.Content, // Content: 0, Element: 1
|
|
423
|
+
(value) => {
|
|
424
|
+
console.log('Content:', value);
|
|
425
|
+
}
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
// Get boolean content
|
|
429
|
+
Insider.getContentBoolWithName(
|
|
430
|
+
'feature_enabled',
|
|
431
|
+
false,
|
|
432
|
+
ContentOptimizerDataType.Element,
|
|
433
|
+
(value) => {
|
|
434
|
+
console.log('Feature enabled:', value);
|
|
435
|
+
}
|
|
436
|
+
);
|
|
437
|
+
|
|
438
|
+
// Get integer content
|
|
439
|
+
Insider.getContentIntWithName(
|
|
440
|
+
'max_items',
|
|
441
|
+
10,
|
|
442
|
+
ContentOptimizerDataType.Content,
|
|
443
|
+
(value) => {
|
|
444
|
+
console.log('Max items:', value);
|
|
445
|
+
}
|
|
446
|
+
);
|
|
447
|
+
|
|
448
|
+
// Without cache (always fetch fresh data)
|
|
449
|
+
Insider.getContentStringWithoutCache(
|
|
450
|
+
'variable_name',
|
|
451
|
+
'default',
|
|
452
|
+
ContentOptimizerDataType.Content,
|
|
453
|
+
(value) => {
|
|
454
|
+
console.log('Fresh content:', value);
|
|
455
|
+
}
|
|
456
|
+
);
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### Push Notifications
|
|
460
|
+
|
|
461
|
+
#### iOS Configuration
|
|
462
|
+
|
|
463
|
+
```typescript
|
|
464
|
+
// Enable quiet permission (iOS only)
|
|
465
|
+
Insider.registerWithQuietPermission(true);
|
|
466
|
+
|
|
467
|
+
// Handle foreground push
|
|
468
|
+
Insider.setForegroundPushCallback((notification) => {
|
|
469
|
+
console.log('Foreground push:', notification);
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// Set active foreground push view
|
|
473
|
+
Insider.setActiveForegroundPushView();
|
|
474
|
+
|
|
475
|
+
// Enable IDFA collection
|
|
476
|
+
Insider.enableIDFACollection(true);
|
|
477
|
+
|
|
478
|
+
// Disable in-app message templates (iOS)
|
|
479
|
+
Insider.disableTemplatesForIOS();
|
|
480
|
+
|
|
481
|
+
// Re-enable templates (iOS)
|
|
482
|
+
Insider.reenableTemplatesForIOS();
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
#### Android Configuration
|
|
486
|
+
|
|
487
|
+
```typescript
|
|
488
|
+
// Set hybrid push token (Android only)
|
|
489
|
+
Insider.setHybridPushToken('your_fcm_token');
|
|
490
|
+
|
|
491
|
+
// Handle universal links (Android only)
|
|
492
|
+
Insider.handleUniversalLink('https://your-link.com/path');
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
#### General Push Methods
|
|
496
|
+
|
|
497
|
+
```typescript
|
|
498
|
+
// Handle notification manually
|
|
499
|
+
Insider.handleNotification(notificationData);
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### In-App Messages
|
|
503
|
+
|
|
504
|
+
```typescript
|
|
505
|
+
// Remove current in-app message
|
|
506
|
+
Insider.removeInapp();
|
|
507
|
+
|
|
508
|
+
// Disable in-app messages
|
|
509
|
+
Insider.disableInAppMessages();
|
|
510
|
+
|
|
511
|
+
// Enable in-app messages
|
|
512
|
+
Insider.enableInAppMessages();
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### Geofencing
|
|
516
|
+
|
|
517
|
+
```typescript
|
|
518
|
+
// Start tracking geofences
|
|
519
|
+
Insider.startTrackingGeofence();
|
|
520
|
+
|
|
521
|
+
// Allow background location updates (iOS)
|
|
522
|
+
Insider.setAllowsBackgroundLocationUpdates(true);
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### GDPR & Privacy
|
|
526
|
+
|
|
527
|
+
```typescript
|
|
528
|
+
// Set GDPR consent
|
|
529
|
+
Insider.setGDPRConsent(true);
|
|
530
|
+
|
|
531
|
+
// Set mobile app access
|
|
532
|
+
Insider.setMobileAppAccess(true);
|
|
533
|
+
|
|
534
|
+
// Enable/disable data collection
|
|
535
|
+
Insider.enableLocationCollection(true);
|
|
536
|
+
Insider.enableIpCollection(true);
|
|
537
|
+
Insider.enableCarrierCollection(true);
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
### Insider ID
|
|
541
|
+
|
|
542
|
+
```typescript
|
|
543
|
+
// Get current Insider ID (returns a Promise)
|
|
544
|
+
const insiderID = await Insider.getInsiderID();
|
|
545
|
+
console.log('Insider ID:', insiderID);
|
|
546
|
+
|
|
547
|
+
// Listen for Insider ID changes
|
|
548
|
+
Insider.insiderIDListener((insiderID) => {
|
|
549
|
+
console.log('Insider ID updated:', insiderID);
|
|
550
|
+
});
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
### Miscellaneous
|
|
554
|
+
|
|
555
|
+
```typescript
|
|
556
|
+
// Show native app review dialog
|
|
557
|
+
Insider.showNativeAppReview();
|
|
558
|
+
|
|
559
|
+
// Reinitialize with new partner name
|
|
560
|
+
Insider.reinitWithPartnerName('new_partner_name');
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
## TypeScript Support
|
|
564
|
+
|
|
565
|
+
The SDK includes full TypeScript definitions:
|
|
566
|
+
|
|
567
|
+
```typescript
|
|
568
|
+
import Insider from 'react-native-insider';
|
|
569
|
+
import InsiderGender from 'react-native-insider/src/InsiderGender';
|
|
570
|
+
import InsiderIdentifier from 'react-native-insider/src/InsiderIdentifier';
|
|
571
|
+
import InsiderCallbackType from 'react-native-insider/src/InsiderCallbackType';
|
|
572
|
+
import ContentOptimizerDataType from 'react-native-insider/src/ContentOptimizerDataType';
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
## Enums
|
|
576
|
+
|
|
577
|
+
### InsiderGender
|
|
578
|
+
|
|
579
|
+
```typescript
|
|
580
|
+
InsiderGender.Male // 0
|
|
581
|
+
InsiderGender.Female // 1
|
|
582
|
+
InsiderGender.Other // 2
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
### InsiderCallbackType
|
|
586
|
+
|
|
587
|
+
```typescript
|
|
588
|
+
InsiderCallbackType.NOTIFICATION_OPEN // 0
|
|
589
|
+
InsiderCallbackType.INAPP_BUTTON_CLICK // 1
|
|
590
|
+
InsiderCallbackType.TEMP_STORE_PURCHASE // 2
|
|
591
|
+
InsiderCallbackType.TEMP_STORE_ADDED_TO_CART // 3
|
|
592
|
+
InsiderCallbackType.TEMP_STORE_CUSTOM_ACTION // 4
|
|
593
|
+
InsiderCallbackType.INAPP_SEEN // 5
|
|
594
|
+
InsiderCallbackType.SESSION_STARTED // 6
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
### ContentOptimizerDataType
|
|
598
|
+
|
|
599
|
+
```typescript
|
|
600
|
+
ContentOptimizerDataType.Content // 0
|
|
601
|
+
ContentOptimizerDataType.Element // 1
|
|
101
602
|
```
|
|
102
|
-
"partnerName" => String - Your Partner Name
|
|
103
603
|
|
|
104
|
-
|
|
604
|
+
## Complete Example
|
|
605
|
+
|
|
606
|
+
```typescript
|
|
607
|
+
import React, { useEffect } from 'react';
|
|
608
|
+
import { Platform, Linking } from 'react-native';
|
|
609
|
+
import Insider from 'react-native-insider';
|
|
610
|
+
import InsiderGender from 'react-native-insider/src/InsiderGender';
|
|
611
|
+
import InsiderIdentifier from 'react-native-insider/src/InsiderIdentifier';
|
|
612
|
+
import InsiderCallbackType from 'react-native-insider/src/InsiderCallbackType';
|
|
613
|
+
|
|
614
|
+
function App() {
|
|
615
|
+
useEffect(() => {
|
|
616
|
+
// Initialize SDK
|
|
617
|
+
Insider.init('your_partner_name', 'group.com.your.app', (type, data) => {
|
|
618
|
+
switch(type) {
|
|
619
|
+
case InsiderCallbackType.NOTIFICATION_OPEN:
|
|
620
|
+
console.log('Notification clicked:', data);
|
|
621
|
+
break;
|
|
622
|
+
case InsiderCallbackType.INAPP_BUTTON_CLICK:
|
|
623
|
+
console.log('In-app button clicked:', data);
|
|
624
|
+
break;
|
|
625
|
+
case InsiderCallbackType.SESSION_STARTED:
|
|
626
|
+
console.log('Session started');
|
|
627
|
+
break;
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
// Configure SDK
|
|
632
|
+
Insider.registerWithQuietPermission(false);
|
|
633
|
+
Insider.setActiveForegroundPushView();
|
|
634
|
+
Insider.startTrackingGeofence();
|
|
635
|
+
Insider.enableIDFACollection(true);
|
|
636
|
+
Insider.enableLocationCollection(true);
|
|
637
|
+
|
|
638
|
+
// Handle deep links (Android)
|
|
639
|
+
if (Platform.OS === 'android') {
|
|
640
|
+
Linking.getInitialURL().then((url) => {
|
|
641
|
+
if (url) {
|
|
642
|
+
Insider.handleUniversalLink(url);
|
|
643
|
+
}
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
const urlListener = Linking.addEventListener('url', (event) => {
|
|
647
|
+
Insider.handleUniversalLink(event.url);
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
return () => urlListener.remove();
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// Set up user
|
|
654
|
+
const user = Insider.getCurrentUser();
|
|
655
|
+
user
|
|
656
|
+
.setName('Jane')
|
|
657
|
+
.setEmail('jane@example.com')
|
|
658
|
+
.setAge(25)
|
|
659
|
+
.setGender(InsiderGender.Female);
|
|
660
|
+
|
|
661
|
+
// Login user
|
|
662
|
+
const identifiers = new InsiderIdentifier()
|
|
663
|
+
.addEmail('jane@example.com')
|
|
664
|
+
.addUserID('user_123');
|
|
665
|
+
user.login(identifiers);
|
|
666
|
+
|
|
667
|
+
// Track page visit
|
|
668
|
+
Insider.visitHomePage();
|
|
105
669
|
|
|
106
|
-
|
|
107
|
-
|
|
670
|
+
// Track custom event
|
|
671
|
+
Insider.tagEvent('app_opened')
|
|
672
|
+
.addParameterWithString('source', 'direct')
|
|
673
|
+
.addParameterWithDate('timestamp', new Date())
|
|
674
|
+
.build();
|
|
675
|
+
|
|
676
|
+
// Create and track product
|
|
677
|
+
const product = Insider.createNewProduct(
|
|
678
|
+
'SKU001',
|
|
679
|
+
'Premium T-Shirt',
|
|
680
|
+
['Clothing', 'T-Shirts'],
|
|
681
|
+
'https://example.com/tshirt.jpg',
|
|
682
|
+
29.99,
|
|
683
|
+
'USD'
|
|
684
|
+
);
|
|
685
|
+
|
|
686
|
+
product.setColor('Blue').setSize('M');
|
|
687
|
+
Insider.visitProductDetailPage(product);
|
|
688
|
+
}, []);
|
|
689
|
+
|
|
690
|
+
return <YourApp />;
|
|
691
|
+
}
|
|
108
692
|
```
|
|
109
|
-
|
|
693
|
+
|
|
694
|
+
## Requirements
|
|
695
|
+
|
|
696
|
+
- React Native >= 0.60
|
|
697
|
+
- iOS >= 11.0
|
|
698
|
+
- Android >= API 21 (Android 5.0)
|
|
699
|
+
|
|
700
|
+
## Support
|
|
701
|
+
|
|
702
|
+
- **Documentation**: [Insider Developer Hub](https://academy.useinsider.com/docs)
|
|
703
|
+
- **GitHub**: [useinsider/react-native-insider](https://github.com/useinsider/react-native-insider)
|
|
704
|
+
- **Issues**: [Report issues](https://github.com/useinsider/react-native-insider/issues)
|
|
705
|
+
- **Email**: Contact your Insider representative
|
|
706
|
+
|
|
707
|
+
## License
|
|
708
|
+
|
|
709
|
+
This SDK is provided by Insider. Please refer to your commercial agreement with Insider for licensing terms.
|
package/RNInsider.podspec
CHANGED
|
@@ -9,12 +9,12 @@ Pod::Spec.new do |s|
|
|
|
9
9
|
s.authors = package_json['author']
|
|
10
10
|
s.license = 'MIT'
|
|
11
11
|
s.platform = :ios, '12.0'
|
|
12
|
-
s.source = {:http => 'https://mobilesdk.useinsider.com/iOS/14.
|
|
12
|
+
s.source = {:http => 'https://mobilesdk.useinsider.com/iOS/14.2.2/InsiderMobileIOSFramework.zip'}
|
|
13
13
|
s.source_files = 'ios/RNInsider/*.{h,m}'
|
|
14
14
|
s.requires_arc = true
|
|
15
15
|
s.static_framework = true
|
|
16
16
|
s.dependency 'React'
|
|
17
|
-
s.dependency 'InsiderMobile', '14.
|
|
18
|
-
s.dependency 'InsiderGeofence', '1.2.
|
|
19
|
-
s.dependency 'InsiderHybrid', '1.7.
|
|
17
|
+
s.dependency 'InsiderMobile', '14.2.2'
|
|
18
|
+
s.dependency 'InsiderGeofence', '1.2.4'
|
|
19
|
+
s.dependency 'InsiderHybrid', '1.7.6'
|
|
20
20
|
end
|
package/android/build.gradle
CHANGED
|
@@ -42,8 +42,8 @@ repositories {
|
|
|
42
42
|
|
|
43
43
|
dependencies {
|
|
44
44
|
implementation "com.facebook.react:react-native:${getVersionFromPartner('reactNativeVersion', '+')}"
|
|
45
|
-
implementation 'com.useinsider:insider:15.1
|
|
46
|
-
implementation 'com.useinsider:insiderhybrid:1.3.
|
|
45
|
+
implementation 'com.useinsider:insider:15.2.1'
|
|
46
|
+
implementation 'com.useinsider:insiderhybrid:1.3.4'
|
|
47
47
|
|
|
48
48
|
implementation 'androidx.security:security-crypto:1.1.0-alpha06'
|
|
49
49
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
|
@@ -335,6 +335,43 @@ public class RNInsiderModule extends ReactContextBaseJavaModule {
|
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
337
|
|
|
338
|
+
@ReactMethod
|
|
339
|
+
public void logoutResettingInsiderID(ReadableArray identifiersArray, final Callback insiderIDResult) {
|
|
340
|
+
try {
|
|
341
|
+
InsiderIdentifiers[] identifiers = convertReadableArrayToInsiderIdentifiersArray(identifiersArray);
|
|
342
|
+
|
|
343
|
+
if (insiderIDResult != null) {
|
|
344
|
+
Insider.Instance.getCurrentUser().logoutResettingInsiderID(identifiers, new InsiderUser.InsiderIDResult() {
|
|
345
|
+
@Override
|
|
346
|
+
public void insiderIDResult(String insiderID) {
|
|
347
|
+
try {
|
|
348
|
+
insiderIDResult.invoke(insiderID);
|
|
349
|
+
} catch (Exception e) {
|
|
350
|
+
Insider.Instance.putException(e);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
} else {
|
|
355
|
+
Insider.Instance.getCurrentUser().logoutResettingInsiderID(identifiers);
|
|
356
|
+
}
|
|
357
|
+
} catch (Exception e) {
|
|
358
|
+
Insider.Instance.putException(e);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
private InsiderIdentifiers[] convertReadableArrayToInsiderIdentifiersArray(ReadableArray identifiersArray) {
|
|
363
|
+
if (identifiersArray == null || identifiersArray.size() == 0) {
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
InsiderIdentifiers[] identifiers = new InsiderIdentifiers[identifiersArray.size()];
|
|
368
|
+
for (int i = 0; i < identifiersArray.size(); i++) {
|
|
369
|
+
ReadableMap identifierMap = identifiersArray.getMap(i);
|
|
370
|
+
identifiers[i] = setIdentifiers(identifierMap);
|
|
371
|
+
}
|
|
372
|
+
return identifiers;
|
|
373
|
+
}
|
|
374
|
+
|
|
338
375
|
@ReactMethod
|
|
339
376
|
public void setCustomAttributeWithString(String key, String value) {
|
|
340
377
|
try {
|
|
@@ -242,6 +242,47 @@ RCT_EXPORT_METHOD(logout) {
|
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
+
RCT_EXPORT_METHOD(logoutResettingInsiderID:(NSArray *)identifiersArray insiderIDResult:(RCTResponseSenderBlock)insiderIDResult) {
|
|
246
|
+
@try {
|
|
247
|
+
NSArray<InsiderIdentifiers *> *identifiers = [self convertReadableArrayToInsiderIdentifiersArray:identifiersArray];
|
|
248
|
+
|
|
249
|
+
if (insiderIDResult != nil) {
|
|
250
|
+
[[Insider getCurrentUser] logoutResettingInsiderID:identifiers insiderIDResult:^(NSString *insiderID) {
|
|
251
|
+
NSString *insiderIDToPass = insiderID ? insiderID : @"";
|
|
252
|
+
insiderIDResult(@[insiderIDToPass]);
|
|
253
|
+
}];
|
|
254
|
+
} else {
|
|
255
|
+
[[Insider getCurrentUser] logoutResettingInsiderID:identifiers];
|
|
256
|
+
}
|
|
257
|
+
} @catch (NSException *e) {
|
|
258
|
+
[Insider sendError:e desc:[NSString stringWithFormat:@"%s:%d", __func__, __LINE__]];
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
- (NSArray<InsiderIdentifiers *> *)convertReadableArrayToInsiderIdentifiersArray:(NSArray *)identifiersArray {
|
|
263
|
+
if (identifiersArray == nil || identifiersArray.count == 0) {
|
|
264
|
+
return nil;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
NSMutableArray<InsiderIdentifiers *> *identifiers = [NSMutableArray array];
|
|
268
|
+
for (NSDictionary *identifierDict in identifiersArray) {
|
|
269
|
+
InsiderIdentifiers *insiderIdentifiers = [[InsiderIdentifiers alloc] init];
|
|
270
|
+
for (NSString *key in identifierDict.allKeys) {
|
|
271
|
+
if ([key isEqualToString:ADD_EMAIL]) {
|
|
272
|
+
insiderIdentifiers.addEmail([identifierDict objectForKey:key]);
|
|
273
|
+
} else if ([key isEqualToString:ADD_PHONE_NUMBER]) {
|
|
274
|
+
insiderIdentifiers.addPhoneNumber([identifierDict objectForKey:key]);
|
|
275
|
+
} else if ([key isEqualToString:ADD_USER_ID]) {
|
|
276
|
+
insiderIdentifiers.addUserID([identifierDict objectForKey:key]);
|
|
277
|
+
} else {
|
|
278
|
+
insiderIdentifiers.addCustomIdentifier(key, [identifierDict objectForKey:key]);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
[identifiers addObject:insiderIdentifiers];
|
|
282
|
+
}
|
|
283
|
+
return identifiers;
|
|
284
|
+
}
|
|
285
|
+
|
|
245
286
|
RCT_EXPORT_METHOD(setCustomAttributeWithString:(NSString *)key value:(NSString *)value) {
|
|
246
287
|
@try {
|
|
247
288
|
[Insider getCurrentUser].setCustomAttributeWithString(key, value);
|
package/package.json
CHANGED
package/src/InsiderProduct.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ declare class RNInsiderProduct {
|
|
|
28
28
|
setDescription(description: string): this;
|
|
29
29
|
setTags(tags: string[]): this;
|
|
30
30
|
setInStock(isInStock: boolean): this;
|
|
31
|
+
setProductURL(productURL: string): this;
|
|
31
32
|
|
|
32
33
|
setCustomAttributeWithString(key: string, value: string): this;
|
|
33
34
|
setCustomAttributeWithInt(key: string, value: number): this;
|
package/src/InsiderProduct.js
CHANGED
|
@@ -34,6 +34,7 @@ const GTIN = 'gt';
|
|
|
34
34
|
const DESCRIPTION = 'desc';
|
|
35
35
|
const TAGS = 'tags';
|
|
36
36
|
const IS_IN_STOCK = 'iis';
|
|
37
|
+
const PRODUCT_URL = 'url';
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
export default class RNInsiderProduct {
|
|
@@ -330,6 +331,20 @@ export default class RNInsiderProduct {
|
|
|
330
331
|
return this;
|
|
331
332
|
}
|
|
332
333
|
|
|
334
|
+
setProductURL(productURL) {
|
|
335
|
+
if (shouldNotProceed()) return this;
|
|
336
|
+
if (checkParameters([{ type: 'string', value: productURL }])) {
|
|
337
|
+
showParameterWarningLog("setProductURL", [{ type: 'string', value: productURL }]);
|
|
338
|
+
return this;
|
|
339
|
+
}
|
|
340
|
+
try {
|
|
341
|
+
this.productOptMap[PRODUCT_URL] = productURL;
|
|
342
|
+
} catch (error) {
|
|
343
|
+
Insider.putErrorLog(generateJSONErrorString(error));
|
|
344
|
+
}
|
|
345
|
+
return this;
|
|
346
|
+
}
|
|
347
|
+
|
|
333
348
|
setCustomAttributeWithString(key, value) {
|
|
334
349
|
if (shouldNotProceed()) return this;
|
|
335
350
|
if (checkParameters([{ type: 'string', value: key }, { type: 'string', value }])) {
|
package/src/InsiderUser.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ declare class RNInsiderUser {
|
|
|
20
20
|
|
|
21
21
|
login(identifiers: RNInsiderIdentifier, insiderIDResult?: (insiderID: string) => void): this;
|
|
22
22
|
logout(): this;
|
|
23
|
+
logoutResettingInsiderID(identifiers?: RNInsiderIdentifier[] | null, insiderIDResult?: (insiderID: string) => void): this;
|
|
23
24
|
|
|
24
25
|
setCustomAttributeWithString(key: string, value: string): this;
|
|
25
26
|
setCustomAttributeWithInt(key: string, value: number): this;
|
package/src/InsiderUser.js
CHANGED
|
@@ -255,6 +255,20 @@ export default class RNInsiderUser {
|
|
|
255
255
|
return this;
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
+
logoutResettingInsiderID(identifiers, insiderIDResult) {
|
|
259
|
+
if (shouldNotProceed()) { return this; }
|
|
260
|
+
try {
|
|
261
|
+
const identifiersArray = (identifiers && Array.isArray(identifiers))
|
|
262
|
+
? identifiers.map(id => id.identifiers)
|
|
263
|
+
: null;
|
|
264
|
+
|
|
265
|
+
Insider.logoutResettingInsiderID(identifiersArray, insiderIDResult);
|
|
266
|
+
} catch (error) {
|
|
267
|
+
Insider.putErrorLog(generateJSONErrorString(error));
|
|
268
|
+
}
|
|
269
|
+
return this;
|
|
270
|
+
}
|
|
271
|
+
|
|
258
272
|
setCustomAttributeWithString(key, value) {
|
|
259
273
|
if (shouldNotProceed()) return this;
|
|
260
274
|
if (checkParameters([{ type: 'string', value: key }, { type: 'string', value }])) {
|