clevertap-react-native 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,26 @@
1
1
  package com.clevertap.react;
2
2
 
3
3
  import android.util.Log;
4
+
5
+ import com.clevertap.android.sdk.displayunits.model.CleverTapDisplayUnit;
4
6
  import com.facebook.react.bridge.Arguments;
7
+ import com.facebook.react.bridge.WritableArray;
8
+ import com.facebook.react.bridge.ReadableArray;
9
+ import com.facebook.react.bridge.ReadableMap;
10
+ import com.facebook.react.bridge.ReadableMapKeySetIterator;
11
+ import com.facebook.react.bridge.ReadableType;
12
+ import com.facebook.react.bridge.WritableArray;
5
13
  import com.facebook.react.bridge.WritableMap;
14
+ import java.util.ArrayList;
15
+ import java.util.HashMap;
6
16
  import java.util.Iterator;
17
+ import java.util.List;
7
18
  import java.util.Map;
19
+
20
+ import org.json.JSONArray;
21
+ import org.json.JSONException;
22
+ import org.json.JSONArray;
23
+ import org.json.JSONException;
8
24
  import org.json.JSONObject;
9
25
 
10
26
  public class CleverTapUtils {
@@ -33,4 +49,281 @@ public class CleverTapUtils {
33
49
  return extrasParams;
34
50
  }
35
51
 
52
+ public static WritableArray getWritableArrayFromDisplayUnitList(List<CleverTapDisplayUnit> list) {
53
+ WritableArray writableArray = Arguments.createArray();
54
+
55
+ if (list != null) {
56
+ for (CleverTapDisplayUnit item : list) {
57
+ if (item != null && item.getJsonObject() != null) {
58
+ WritableMap displayUnitMap = convertObjectToWritableMap(item.getJsonObject());
59
+ writableArray.pushMap(displayUnitMap);
60
+ }
61
+ }
62
+ }
63
+
64
+ return writableArray;
65
+ }
66
+
67
+ public static WritableMap convertObjectToWritableMap(JSONObject jsonObject) {
68
+ WritableMap writableMap = Arguments.createMap();
69
+
70
+ Iterator<String> keys = jsonObject.keys();
71
+ while (keys.hasNext()) {
72
+ String key = keys.next();
73
+ try {
74
+ Object value = jsonObject.get(key);
75
+
76
+ if (value instanceof String) {
77
+ writableMap.putString(key, (String) value);
78
+ } else if (value instanceof Integer) {
79
+ writableMap.putInt(key, (Integer) value);
80
+ } else if (value instanceof Boolean) {
81
+ writableMap.putBoolean(key, (Boolean) value);
82
+ } else if (value instanceof Float || value instanceof Double) {
83
+ writableMap.putDouble(key, Double.parseDouble(value.toString()));
84
+ } else if (value instanceof JSONObject) {
85
+ WritableMap nestedWritableMap = convertObjectToWritableMap((JSONObject) value);
86
+ writableMap.putMap(key, nestedWritableMap);
87
+ } else if (value instanceof JSONArray) {
88
+ WritableArray nestedWritableArray = convertArrayToWritableArray((JSONArray) value);
89
+ writableMap.putArray(key, nestedWritableArray);
90
+ }
91
+ } catch (JSONException e) {
92
+ e.printStackTrace();
93
+ }
94
+ }
95
+
96
+ return writableMap;
97
+ }
98
+
99
+ private static WritableArray convertArrayToWritableArray(JSONArray jsonArray) {
100
+ WritableArray writableArray = Arguments.createArray();
101
+
102
+ for (int i = 0; i < jsonArray.length(); i++) {
103
+ try {
104
+ Object value = jsonArray.get(i);
105
+
106
+ if (value instanceof String) {
107
+ writableArray.pushString((String) value);
108
+ } else if (value instanceof Integer) {
109
+ writableArray.pushInt((Integer) value);
110
+ } else if (value instanceof Boolean) {
111
+ writableArray.pushBoolean((Boolean) value);
112
+ } else if (value instanceof Float || value instanceof Double) {
113
+ writableArray.pushDouble(Double.parseDouble(value.toString()));
114
+ } else if (value instanceof JSONObject) {
115
+ WritableMap nestedWritableMap = convertObjectToWritableMap((JSONObject) value);
116
+ writableArray.pushMap(nestedWritableMap);
117
+ } else if (value instanceof JSONArray) {
118
+ WritableArray nestedWritableArray = convertArrayToWritableArray((JSONArray) value);
119
+ writableArray.pushArray(nestedWritableArray);
120
+ }
121
+ } catch (JSONException e) {
122
+ e.printStackTrace();
123
+ }
124
+ }
125
+
126
+ return writableArray;
127
+ }
128
+
129
+ public static class MapUtil {
130
+
131
+ public static JSONObject toJSONObject(ReadableMap readableMap) throws JSONException {
132
+ JSONObject jsonObject = new JSONObject();
133
+
134
+ ReadableMapKeySetIterator iterator = readableMap.keySetIterator();
135
+
136
+ while (iterator.hasNextKey()) {
137
+ String key = iterator.nextKey();
138
+ ReadableType type = readableMap.getType(key);
139
+
140
+ switch (type) {
141
+ case Null:
142
+ jsonObject.put(key, null);
143
+ break;
144
+ case Boolean:
145
+ jsonObject.put(key, readableMap.getBoolean(key));
146
+ break;
147
+ case Number:
148
+ jsonObject.put(key, readableMap.getDouble(key));
149
+ break;
150
+ case String:
151
+ jsonObject.put(key, readableMap.getString(key));
152
+ break;
153
+ case Map:
154
+ jsonObject.put(key, MapUtil.toJSONObject(readableMap.getMap(key)));
155
+ break;
156
+ case Array:
157
+ jsonObject.put(key, ArrayUtil.toJSONArray(readableMap.getArray(key)));
158
+ break;
159
+ }
160
+ }
161
+
162
+ return jsonObject;
163
+ }
164
+
165
+
166
+ public static Map<String, Object> toMap(ReadableMap readableMap) {
167
+ Map<String, Object> map = new HashMap<>();
168
+ ReadableMapKeySetIterator iterator = readableMap.keySetIterator();
169
+
170
+ while (iterator.hasNextKey()) {
171
+ String key = iterator.nextKey();
172
+ ReadableType type = readableMap.getType(key);
173
+
174
+ switch (type) {
175
+ case Null:
176
+ map.put(key, null);
177
+ break;
178
+ case Boolean:
179
+ map.put(key, readableMap.getBoolean(key));
180
+ break;
181
+ case Number:
182
+ map.put(key, readableMap.getDouble(key));
183
+ break;
184
+ case String:
185
+ map.put(key, readableMap.getString(key));
186
+ break;
187
+ case Map:
188
+ map.put(key, MapUtil.toMap(readableMap.getMap(key)));
189
+ break;
190
+ case Array:
191
+ map.put(key, ArrayUtil.toArray(readableMap.getArray(key)));
192
+ break;
193
+ }
194
+ }
195
+
196
+ return map;
197
+ }
198
+
199
+ public static WritableMap toWritableMap(Map<String, Object> map) {
200
+ WritableMap writableMap = Arguments.createMap();
201
+ Iterator iterator = map.entrySet().iterator();
202
+
203
+ while (iterator.hasNext()) {
204
+ Map.Entry pair = (Map.Entry) iterator.next();
205
+ writableMap.merge(addValue((String) pair.getKey(), pair.getValue()));
206
+ iterator.remove();
207
+ }
208
+
209
+ return writableMap;
210
+ }
211
+
212
+ public static WritableMap addValue(String key, Object value) {
213
+ WritableMap writableMap = Arguments.createMap();
214
+ if (value == null) {
215
+ writableMap.putNull(key);
216
+ } else if (value instanceof Boolean) {
217
+ writableMap.putBoolean(key, (Boolean) value);
218
+ } else if (value instanceof Double) {
219
+ writableMap.putDouble(key, (Double) value);
220
+ } else if (value instanceof Integer) {
221
+ writableMap.putInt(key, (Integer) value);
222
+ } else if (value instanceof String) {
223
+ writableMap.putString(key, (String) value);
224
+ } else if (value instanceof Map) {
225
+ writableMap.putMap(key, MapUtil.toWritableMap((Map<String, Object>) value));
226
+ } else if (value.getClass() != null && (value.getClass().isArray() || value instanceof ArrayList)) {
227
+ writableMap.putArray(key, ArrayUtil.toWritableArray((ArrayList) value));
228
+ }
229
+ return writableMap;
230
+ }
231
+
232
+ public static class ArrayUtil {
233
+
234
+ public static JSONArray toJSONArray(ReadableArray readableArray) throws JSONException {
235
+ JSONArray jsonArray = new JSONArray();
236
+
237
+ for (int i = 0; i < readableArray.size(); i++) {
238
+ ReadableType type = readableArray.getType(i);
239
+
240
+ switch (type) {
241
+ case Null:
242
+ jsonArray.put(i, null);
243
+ break;
244
+ case Boolean:
245
+ jsonArray.put(i, readableArray.getBoolean(i));
246
+ break;
247
+ case Number:
248
+ jsonArray.put(i, readableArray.getDouble(i));
249
+ break;
250
+ case String:
251
+ jsonArray.put(i, readableArray.getString(i));
252
+ break;
253
+ case Map:
254
+ jsonArray.put(i, MapUtil.toJSONObject(readableArray.getMap(i)));
255
+ break;
256
+ case Array:
257
+ jsonArray.put(i, ArrayUtil.toJSONArray(readableArray.getArray(i)));
258
+ break;
259
+ }
260
+ }
261
+
262
+ return jsonArray;
263
+ }
264
+
265
+ public static Object[] toArray(ReadableArray readableArray) {
266
+ Object[] array = new Object[readableArray.size()];
267
+
268
+ for (int i = 0; i < readableArray.size(); i++) {
269
+ ReadableType type = readableArray.getType(i);
270
+
271
+ switch (type) {
272
+ case Null:
273
+ array[i] = null;
274
+ break;
275
+ case Boolean:
276
+ array[i] = readableArray.getBoolean(i);
277
+ break;
278
+ case Number:
279
+ array[i] = readableArray.getDouble(i);
280
+ break;
281
+ case String:
282
+ array[i] = readableArray.getString(i);
283
+ break;
284
+ case Map:
285
+ array[i] = MapUtil.toMap(readableArray.getMap(i));
286
+ break;
287
+ case Array:
288
+ array[i] = ArrayUtil.toArray(readableArray.getArray(i));
289
+ break;
290
+ }
291
+ }
292
+
293
+ return array;
294
+ }
295
+
296
+ public static WritableArray toWritableArray(ArrayList arrayList) {
297
+ WritableArray writableArray = Arguments.createArray();
298
+
299
+ for (int i = 0; i < arrayList.size(); i++) {
300
+ Object value = arrayList.get(i);
301
+
302
+ if (value == null) {
303
+ writableArray.pushNull();
304
+ }
305
+ if (value instanceof Boolean) {
306
+ writableArray.pushBoolean((Boolean) value);
307
+ }
308
+ if (value instanceof Double) {
309
+ writableArray.pushDouble((Double) value);
310
+ }
311
+ if (value instanceof Integer) {
312
+ writableArray.pushInt((Integer) value);
313
+ }
314
+ if (value instanceof String) {
315
+ writableArray.pushString((String) value);
316
+ }
317
+ if (value instanceof Map) {
318
+ writableArray.pushMap(MapUtil.toWritableMap((Map<String, Object>) value));
319
+ }
320
+ if (value.getClass().isArray()) {
321
+ writableArray.pushArray(ArrayUtil.toWritableArray((ArrayList) value));
322
+ }
323
+ }
324
+
325
+ return writableArray;
326
+ }
327
+ }
328
+ }
36
329
  }
@@ -18,6 +18,6 @@ Pod::Spec.new do |s|
18
18
  s.preserve_paths = 'LICENSE.md', 'README.md', 'package.json', 'index.js'
19
19
  s.source_files = 'ios/CleverTapReact/*.{h,m}'
20
20
 
21
- s.dependency 'CleverTap-iOS-SDK', '4.2.2'
21
+ s.dependency 'CleverTap-iOS-SDK', '5.0.1'
22
22
  s.dependency 'React-Core'
23
23
  end
@@ -0,0 +1,136 @@
1
+ # Overview
2
+ You can define variables using the CleverTap React Native SDK. When you define a variable in your code, you can sync them to the CleverTap Dashboard via the provided SDK methods.
3
+
4
+ # Supported Variable Types
5
+
6
+ Currently, CleverTap SDK supports the following variable types:
7
+
8
+ - String
9
+ - boolean
10
+ - JSON Object
11
+ - number
12
+
13
+ # Define Variables
14
+
15
+ Variables can be defined using the `defineVariables` method. You must provide the names and default values of the variables using a JSON Object.
16
+
17
+ ```javascript
18
+ let variables = {
19
+ 'reactnative_var_string': 'reactnative_var_string_value',
20
+ 'reactnative_var_map': {
21
+ 'reactnative_var_map_string': 'reactnative_var_map_value'
22
+ },
23
+ 'reactnative_var_int': 6,
24
+ 'reactnative_var_float': 6.9,
25
+ 'reactnative_var_boolean': true
26
+ };
27
+ CleverTap.defineVariables(variables);
28
+ ```
29
+
30
+ # Setup Callbacks
31
+
32
+ CleverTap React Native SDK provides several callbacks for the developer to receive feedback from the SDK. You can use them as per your requirement, using all of them is not mandatory. They are as follows:
33
+
34
+ - Status of fetch variables request
35
+ - `onVariablesChanged`
36
+ - `onValueChanged`
37
+
38
+ ## Status of Variables Fetch Request
39
+
40
+ This method provides a boolean flag to ensure that the variables are successfully fetched from the server.
41
+
42
+ ```javascript
43
+ CleverTap.fetchVariables((err, success) => {
44
+ console.log('fetchVariables result: ', success);
45
+ });
46
+ ```
47
+
48
+ ## `onVariablesChanged`
49
+
50
+ This callback is invoked when variables are initialized with values fetched from the server. It is called each time new values are fetched.
51
+
52
+ ```javascript
53
+ CleverTap.onVariablesChanged((variables) => {
54
+ console.log('onVariablesChanged: ', variables);
55
+ });
56
+ ```
57
+
58
+ ## `onValueChanged`
59
+
60
+ This callback is invoked when the value of the variable changes. You must provide the name of the variable whose value needs to be observed.
61
+
62
+ ```javascript
63
+ CleverTap.onValueChanged('reactnative_var_string', (variable) => {
64
+ console.log('onValueChanged: ', variable);
65
+ });
66
+ ```
67
+
68
+ # Sync Defined Variables
69
+
70
+ After defining your variables in the code, you must send/sync variables to the server. To do so, the app must be in DEBUG mode and mark a particular CleverTap user profile as a test profile from the CleverTap dashboard. [Learn how to mark a profile as **Test Profile**](https://developer.clevertap.com/docs/concepts-user-profiles#mark-a-user-profile-as-a-test-profile)
71
+
72
+ After marking the profile as a test profile, you must sync the app variables in DEBUG mode:
73
+
74
+ ```javascript
75
+ // 1. Define CleverTap variables
76
+ // …
77
+ // 2. Add variables/values changed callbacks
78
+ // …
79
+
80
+ // 3. Sync CleverTap Variables from DEBUG mode/builds
81
+ CleverTap.syncVariables();
82
+ ```
83
+
84
+ > 📘 Key Points to Remember
85
+ >
86
+ > - In a scenario where there is already a draft created by another user profile in the dashboard, the sync call will fail to avoid overriding important changes made by someone else. In this case, Publish or Dismiss the existing draft before you proceed with syncing variables again. However, you can override a draft you created via the sync method previously to optimize the integration experience.
87
+ > - You can receive the following console logs from the CleverTap SDK:
88
+ > - Variables synced successfully.
89
+ > - Unauthorized access from a non-test profile. Please mark this profile as a test profile from the CleverTap dashboard.
90
+
91
+ # Fetch Variables During a Session
92
+
93
+ You can fetch the updated values for your CleverTap variables from the server during a session. If variables have changed, the appropriate callbacks will be fired. The provided callback provides a boolean flag that indicates if the fetch call was successful. The callback is fired regardless of whether the variables have changed or not.
94
+
95
+ ```javascript
96
+ CleverTap.fetchVariables((err, success) => {
97
+ console.log('fetchVariables result: ', success);
98
+ });
99
+ ```
100
+
101
+ # Use Fetched Variables Values
102
+
103
+ This process involves the following two major steps:
104
+
105
+ 1. Fetch variable values.
106
+ 2. Access variable values.
107
+
108
+ ## Fetch Variable Values
109
+
110
+ Variables are updated automatically when server values are received. If you want to receive feedback when a specific variable is updated, use the individual callback:
111
+
112
+ ```javascript
113
+ CleverTap.onValueChanged('reactnative_var_string', (variable) => {
114
+ console.log('onValueChanged: ', variable);
115
+ });
116
+ ```
117
+
118
+ ## Access Variable Values
119
+
120
+ You can access these fetched values in the following two ways:
121
+
122
+ ### Getting all variables
123
+
124
+ ```javascript
125
+ CleverTap.getVariables((err, variables) => {
126
+ console.log('getVariables: ', variables, err);
127
+ });
128
+ ```
129
+
130
+ ### Getting a specific variable
131
+
132
+ ```javascript
133
+ CleverTap.getVariable('reactnative_var_string', (err, variable) => {
134
+ console.log(`variable value for key \'reactnative_var_string\': ${variable}`);
135
+ });
136
+ ```
@@ -0,0 +1,26 @@
1
+ ## 🔖 Overview
2
+
3
+ This document demonstrates the changes in the payload formats along with the platform affected. These changes make the payload consistent across Android and iOS platform from v1.1.0.
4
+
5
+ Refer [Sample App](https://github.com/CleverTap/clevertap-react-native/blob/master/Example/App.js) for examples on how to access the payload.
6
+
7
+ | Callback | Platform affected | Old Payload Format | New Payload Format | Remarks |
8
+ | --------------------------------------- | ----------------- | -------------------------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
9
+ | CleverTapInAppNotificationButtonTapped | iOS | { "customExtras": {} } | {} | Removed \`customExtras\` key |
10
+ | CleverTapInAppNotificationDismissed | iOS | { "actionExtras": {} } | { "extras": {}, "actionExtras": {} } | Started passing an empty Object to \`extras\` key when found null |
11
+ | CleverTapInAppNotificationShowed | Android | { "data": '{}' } | { "data": {} } | Removed stringified JSON with plain JSON format to access payload without JSON parsing |
12
+ | CleverTapPushNotificationClicked | iOS | { "customExtras": {} } | {} | Removed \`customExtras\` key |
13
+ | CleverTapPushPermissionResponseReceived | iOS | { "isPermissionGranted": false } | { "accepted": false } | Renamed \`isPersmissionGranted\` key to \`accepted\` |
14
+ | CleverTapInboxDidInitialize | iOS | undefined | {} | Passed an empty Object when found null |
15
+ | CleverTapInboxMessagesDidUpdate | iOS | undefined | {} | Passed an empty Object when found null |
16
+ | CleverTapInboxMessageTapped | Both | { "data": '{}' } | { "data": {}, "contentPageIndex": 0, "buttonIndex": 1 } | \- Replaced stringified JSON with plain JSON format to access the \`data\` key without JSON parsing<br>\- Added \`contentPageIndex\` and \`buttonIndex\` keys to the payload |
17
+ | CleverTapDisplayUnitsLoaded | Android | { "displayUnits": [ '{}' ] } | { "displayUnits": [ {} ] } | Removed stringified JSON with plain JSON format to access payload without JSON parsing |
18
+ | CleverTapFeatureFlagsDidUpdate | iOS | undefined | {} | Passed an empty Object when found null |
19
+ | CleverTapProductConfigDidInitialize | iOS | undefined | {} | Passed an empty Object when found null |
20
+ | CleverTapProductConfigDidFetch | iOS | undefined | {} | Passed an empty Object when found null |
21
+ | CleverTapProductConfigDidActivate | iOS | undefined | {} | Passed an empty Object when found null |
22
+ | getAllInboxMessages | Android | [ '{}' , '{}' ] | [ {}, {} ] | Removed stringified JSON with plain JSON format to access payload without JSON parsing |
23
+ | getUnreadInboxMessages | Android | [ '{}' , '{}' ] | [ {}, {} ] | Removed stringified JSON with plain JSON format to access payload without JSON parsing |
24
+ | getInboxMessageForId | Android | "{}" | {} | Removed stringified JSON with plain JSON format to access payload without JSON parsing |
25
+ | getAllDisplayUnits | Android | [ '{}' , '{}' ] | [ {}, {} ] | Removed stringified JSON with plain JSON format to access payload without JSON parsing |
26
+ | getDisplayUnitForId | Android | "{}" | {} | Removed stringified JSON with plain JSON format to access payload without JSON parsing |
package/docs/usage.md CHANGED
@@ -104,6 +104,37 @@ CleverTap.showInbox({'tabs':['Offers','Promotions'],'navBarTitle':'My App Inbox'
104
104
  'noMessageText':'No message(s)','noMessageTextColor':'#FF0000'});
105
105
  ```
106
106
 
107
+ #### App Inbox Item Click Callback
108
+
109
+ ```javascript
110
+ CleverTap.addListener(CleverTap.CleverTapInboxMessageTapped, (event) => {
111
+ console.log("App Inbox item: ", event.data);
112
+ //following contentPageIndex and buttonIndex fields are available from CleverTap React Native SDK v0.9.6 onwards and below v1.0.0
113
+ console.log("Content Page index: " + event.contentPageIndex);
114
+ console.log("Button index: " + event.buttonIndex);
115
+ });
116
+ ```
117
+
118
+ #### App Inbox Button Click Callback
119
+ ```javascript
120
+ CleverTap.addListener(CleverTap.CleverTapInboxMessageButtonTapped, (event) => {/*consume the payload*/});
121
+ ```
122
+
123
+ #### Dismiss the App Inbox
124
+ ```javascript
125
+ CleverTap.dismissInbox();
126
+ ```
127
+
128
+ ### Mark read all inbox messages by array of messageIds
129
+ ```javascript
130
+ CleverTap.markReadInboxMessagesForIDs(['1', '2', '3']);
131
+ ```
132
+
133
+ ### Delete all inbox messages by array of messageIds
134
+ ```javascript
135
+ CleverTap.deleteInboxMessagesForIDs(['1', '2', '3']);
136
+ ```
137
+
107
138
  #### Get Total message count
108
139
 
109
140
  ```javascript