@appmetrica/react-native-analytics 3.2.0 → 3.4.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/android/build.gradle +1 -1
- package/android/src/main/java/io/appmetrica/analytics/reactnative/AppMetricaModule.java +73 -7
- package/android/src/main/java/io/appmetrica/analytics/reactnative/AppMetricaPackage.java +1 -0
- package/android/src/main/java/io/appmetrica/analytics/reactnative/ExceptionSerializer.java +91 -0
- package/android/src/main/java/io/appmetrica/analytics/reactnative/ExternalAttributionSerializer.java +44 -0
- package/android/src/main/java/io/appmetrica/analytics/reactnative/ReactNativeDeferredDeeplinkListener.java +48 -0
- package/android/src/main/java/io/appmetrica/analytics/reactnative/ReactNativeDeferredDeeplinkParametersListener.java +53 -0
- package/android/src/main/java/io/appmetrica/analytics/reactnative/ReporterModule.java +130 -0
- package/android/src/main/java/io/appmetrica/analytics/reactnative/Utils.java +55 -1
- package/appmetrica-react-native-analytics.podspec +1 -1
- package/ios/AMARNAppMetrica.m +92 -4
- package/ios/AMARNAppMetricaUtils.h +1 -0
- package/ios/AMARNAppMetricaUtils.m +46 -0
- package/ios/AMARNExceptionSerializer.h +6 -0
- package/ios/AMARNExceptionSerializer.m +65 -0
- package/ios/AMARNExternalAttribution.h +4 -0
- package/ios/AMARNExternalAttribution.m +28 -0
- package/ios/AMARNReporter.h +6 -0
- package/ios/AMARNReporter.m +131 -0
- package/lib/commonjs/deferredDeeplink.js +2 -0
- package/lib/commonjs/deferredDeeplink.js.map +1 -0
- package/lib/commonjs/error.js +71 -0
- package/lib/commonjs/error.js.map +1 -0
- package/lib/commonjs/externalAttribution.js +46 -0
- package/lib/commonjs/externalAttribution.js.map +1 -0
- package/lib/commonjs/index.js +68 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/reporter.js +69 -0
- package/lib/commonjs/reporter.js.map +1 -0
- package/lib/module/deferredDeeplink.js +2 -0
- package/lib/module/deferredDeeplink.js.map +1 -0
- package/lib/module/error.js +63 -0
- package/lib/module/error.js.map +1 -0
- package/lib/module/externalAttribution.js +39 -0
- package/lib/module/externalAttribution.js.map +1 -0
- package/lib/module/index.js +46 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/reporter.js +62 -0
- package/lib/module/reporter.js.map +1 -0
- package/lib/typescript/src/deferredDeeplink.d.ts +10 -0
- package/lib/typescript/src/deferredDeeplink.d.ts.map +1 -0
- package/lib/typescript/src/error.d.ts +19 -0
- package/lib/typescript/src/error.d.ts.map +1 -0
- package/lib/typescript/src/externalAttribution.d.ts +15 -0
- package/lib/typescript/src/externalAttribution.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +22 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/reporter.d.ts +51 -0
- package/lib/typescript/src/reporter.d.ts.map +1 -0
- package/package.json +3 -1
- package/src/deferredDeeplink.ts +11 -0
- package/src/error.ts +87 -0
- package/src/externalAttribution.ts +56 -0
- package/src/index.ts +87 -4
- package/src/reporter.ts +126 -0
package/android/build.gradle
CHANGED
|
@@ -85,5 +85,5 @@ dependencies {
|
|
|
85
85
|
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
|
|
86
86
|
//noinspection GradleDynamicVersion
|
|
87
87
|
implementation "com.facebook.react:react-native:+"
|
|
88
|
-
implementation "io.appmetrica.analytics:analytics:7.
|
|
88
|
+
implementation "io.appmetrica.analytics:analytics:7.8.0"
|
|
89
89
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
package io.appmetrica.analytics.reactnative;
|
|
2
2
|
|
|
3
|
-
import android.
|
|
3
|
+
import android.text.TextUtils;
|
|
4
4
|
import android.util.Log;
|
|
5
5
|
import androidx.annotation.NonNull;
|
|
6
6
|
import com.facebook.react.bridge.Callback;
|
|
@@ -12,9 +12,14 @@ import com.facebook.react.bridge.ReadableArray;
|
|
|
12
12
|
import com.facebook.react.bridge.ReadableMap;
|
|
13
13
|
import com.facebook.react.module.annotations.ReactModule;
|
|
14
14
|
|
|
15
|
+
import java.util.Iterator;
|
|
16
|
+
import java.util.Map;
|
|
17
|
+
|
|
15
18
|
import io.appmetrica.analytics.AppMetrica;
|
|
16
19
|
import io.appmetrica.analytics.AppMetricaConfig;
|
|
20
|
+
import io.appmetrica.analytics.ModulesFacade;
|
|
17
21
|
import io.appmetrica.analytics.ecommerce.ECommerceEvent;
|
|
22
|
+
import io.appmetrica.analytics.plugins.PluginErrorDetails;
|
|
18
23
|
|
|
19
24
|
@ReactModule(name = AppMetricaModule.NAME)
|
|
20
25
|
public class AppMetricaModule extends ReactContextBaseJavaModule {
|
|
@@ -66,12 +71,9 @@ public class AppMetricaModule extends ReactContextBaseJavaModule {
|
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
@ReactMethod
|
|
69
|
-
public void reportError(String identifier, String message) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
} catch (Throwable error) {
|
|
73
|
-
AppMetrica.reportError(identifier, message, error);
|
|
74
|
-
}
|
|
74
|
+
public void reportError(String identifier, String message, ReadableMap _reason) {
|
|
75
|
+
PluginErrorDetails errorDetails = _reason != null ? ExceptionSerializer.fromObject(_reason) : null;
|
|
76
|
+
AppMetrica.getPluginExtension().reportError(identifier, message, errorDetails);
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
@ReactMethod
|
|
@@ -151,4 +153,68 @@ public class AppMetricaModule extends ReactContextBaseJavaModule {
|
|
|
151
153
|
public void putErrorEnvironmentValue(String key, String value) {
|
|
152
154
|
AppMetrica.putErrorEnvironmentValue(key, value);
|
|
153
155
|
}
|
|
156
|
+
|
|
157
|
+
@ReactMethod
|
|
158
|
+
public void reportErrorWithoutIdentifier(String message, ReadableMap error) {
|
|
159
|
+
PluginErrorDetails details = ExceptionSerializer.fromObject(error);
|
|
160
|
+
if (details.getStacktrace().isEmpty()) {
|
|
161
|
+
AppMetrica.getPluginExtension().reportError("Errors without stacktrace", message, details);
|
|
162
|
+
} else {
|
|
163
|
+
AppMetrica.getPluginExtension().reportError(details, message);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@ReactMethod
|
|
168
|
+
public void reportUnhandledException(ReadableMap error) {
|
|
169
|
+
PluginErrorDetails details = ExceptionSerializer.fromObject(error);
|
|
170
|
+
AppMetrica.getPluginExtension().reportUnhandledException(details);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@ReactMethod
|
|
174
|
+
public void reportExternalAttribution(ReadableMap attribution) {
|
|
175
|
+
ModulesFacade.reportExternalAttribution(
|
|
176
|
+
ExternalAttributionSerializer.parseSource(attribution.getString("source")),
|
|
177
|
+
ExternalAttributionSerializer.parseValue(attribution.getMap("value"))
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@ReactMethod
|
|
182
|
+
public void putAppEnvironmentValue(String key, String value) {
|
|
183
|
+
AppMetrica.putAppEnvironmentValue(key, value);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@ReactMethod
|
|
187
|
+
public void clearAppEnvironment() {
|
|
188
|
+
AppMetrica.clearAppEnvironment();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@ReactMethod
|
|
192
|
+
public void activateReporter(ReadableMap configMap) {
|
|
193
|
+
AppMetrica.activateReporter(reactContext, Utils.toReporterConfig(configMap));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
@ReactMethod
|
|
197
|
+
public void touchReporter(String apiKey) {
|
|
198
|
+
AppMetrica.getReporter(reactContext, apiKey);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@ReactMethod
|
|
202
|
+
public void getDeviceId(Promise promise) {
|
|
203
|
+
promise.resolve(AppMetrica.getDeviceId(reactContext));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
@ReactMethod
|
|
207
|
+
public void getUuid(Promise promise) {
|
|
208
|
+
promise.resolve(AppMetrica.getUuid(reactContext));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
@ReactMethod
|
|
212
|
+
public void requestDeferredDeeplink(Callback failureCallback, Callback successCallback) {
|
|
213
|
+
AppMetrica.requestDeferredDeeplink(new ReactNativeDeferredDeeplinkListener(failureCallback, successCallback));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
@ReactMethod
|
|
217
|
+
public void requestDeferredDeeplinkParameters(Callback failureCallback, Callback successCallback) {
|
|
218
|
+
AppMetrica.requestDeferredDeeplinkParameters(new ReactNativeDeferredDeeplinkParametersListener(failureCallback, successCallback));
|
|
219
|
+
}
|
|
154
220
|
}
|
|
@@ -17,6 +17,7 @@ public class AppMetricaPackage implements ReactPackage {
|
|
|
17
17
|
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
|
|
18
18
|
List<NativeModule> modules = new ArrayList<>();
|
|
19
19
|
modules.add(new AppMetricaModule(reactContext));
|
|
20
|
+
modules.add(new ReporterModule(reactContext));
|
|
20
21
|
return modules;
|
|
21
22
|
}
|
|
22
23
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
package io.appmetrica.analytics.reactnative;
|
|
2
|
+
|
|
3
|
+
import android.util.Log;
|
|
4
|
+
|
|
5
|
+
import androidx.annotation.NonNull;
|
|
6
|
+
import androidx.annotation.Nullable;
|
|
7
|
+
|
|
8
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
9
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
10
|
+
|
|
11
|
+
import java.util.LinkedList;
|
|
12
|
+
import java.util.List;
|
|
13
|
+
|
|
14
|
+
import io.appmetrica.analytics.plugins.PluginErrorDetails;
|
|
15
|
+
import io.appmetrica.analytics.plugins.StackTraceItem;
|
|
16
|
+
|
|
17
|
+
final class ExceptionSerializer {
|
|
18
|
+
private ExceptionSerializer() {}
|
|
19
|
+
private static final String TAG = "ExceptionSerializer";
|
|
20
|
+
|
|
21
|
+
@NonNull
|
|
22
|
+
public static PluginErrorDetails fromObject(@NonNull ReadableMap exception) {
|
|
23
|
+
PluginErrorDetails.Builder builder = new PluginErrorDetails.Builder();
|
|
24
|
+
builder.withPlatform(PluginErrorDetails.Platform.REACT_NATIVE);
|
|
25
|
+
if (exception.hasKey("errorName")) {
|
|
26
|
+
builder.withExceptionClass(exception.getString("errorName"));
|
|
27
|
+
}
|
|
28
|
+
if (exception.hasKey("message")) {
|
|
29
|
+
builder.withMessage(exception.getString("message"));
|
|
30
|
+
}
|
|
31
|
+
if (exception.hasKey("stackTrace")) {
|
|
32
|
+
builder.withStacktrace(getStackTrace(exception.getArray("stackTrace")));
|
|
33
|
+
}
|
|
34
|
+
if (exception.hasKey("virtualMachineVersion")) {
|
|
35
|
+
builder.withVirtualMachineVersion(exception.getString("virtualMachineVersion"));
|
|
36
|
+
}
|
|
37
|
+
if (exception.hasKey("pluginEnvironment")) {
|
|
38
|
+
builder.withPluginEnvironment(Utils.toMapOfStrings(exception.getMap("pluginEnvironment")));
|
|
39
|
+
}
|
|
40
|
+
return builder.build();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@Nullable
|
|
44
|
+
private static List<StackTraceItem> getStackTrace(@Nullable ReadableArray stackTraceArray) {
|
|
45
|
+
if (stackTraceArray == null) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
List<StackTraceItem> items = new LinkedList<>();
|
|
49
|
+
for (int idx = 0; idx < stackTraceArray.toArrayList().size(); idx++) {
|
|
50
|
+
items.add(getStackTraceItem(stackTraceArray.getMap(idx)));
|
|
51
|
+
}
|
|
52
|
+
return items;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@NonNull
|
|
56
|
+
private static StackTraceItem getStackTraceItem(@Nullable ReadableMap item) {
|
|
57
|
+
StackTraceItem.Builder builder = new StackTraceItem.Builder();
|
|
58
|
+
if (item == null) {
|
|
59
|
+
return builder.build();
|
|
60
|
+
}
|
|
61
|
+
if (item.hasKey("fileName")) {
|
|
62
|
+
builder.withFileName(item.getString("fileName"));
|
|
63
|
+
}
|
|
64
|
+
if (item.hasKey("className")) {
|
|
65
|
+
builder.withClassName(item.getString("className"));
|
|
66
|
+
}
|
|
67
|
+
if (item.hasKey("methodName")) {
|
|
68
|
+
builder.withMethodName(item.getString("methodName"));
|
|
69
|
+
}
|
|
70
|
+
if (item.hasKey("line")) {
|
|
71
|
+
builder.withLine(parseInt(item.getString("line")));
|
|
72
|
+
}
|
|
73
|
+
if (item.hasKey("column")) {
|
|
74
|
+
builder.withColumn(parseInt(item.getString("column")));
|
|
75
|
+
}
|
|
76
|
+
return builder.build();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@Nullable
|
|
80
|
+
private static Integer parseInt(@Nullable String string) {
|
|
81
|
+
if (string == null) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
return Integer.parseInt(string);
|
|
86
|
+
} catch (NumberFormatException exception) {
|
|
87
|
+
Log.w(TAG, "uncorrected number in the stacktrace line or column: " + string);
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
package/android/src/main/java/io/appmetrica/analytics/reactnative/ExternalAttributionSerializer.java
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
package io.appmetrica.analytics.reactnative;
|
|
2
|
+
|
|
3
|
+
import android.text.TextUtils;
|
|
4
|
+
|
|
5
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
6
|
+
|
|
7
|
+
import org.json.JSONObject;
|
|
8
|
+
|
|
9
|
+
import io.appmetrica.analytics.ModulesFacade;
|
|
10
|
+
|
|
11
|
+
final class ExternalAttributionSerializer {
|
|
12
|
+
private ExternalAttributionSerializer() {}
|
|
13
|
+
|
|
14
|
+
public static int parseSource(String sourceString) {
|
|
15
|
+
if (TextUtils.isEmpty(sourceString)) {
|
|
16
|
+
return -1;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
switch (sourceString) {
|
|
20
|
+
case "AppsFlyer":
|
|
21
|
+
return ModulesFacade.EXTERNAL_ATTRIBUTION_APPSFLYER;
|
|
22
|
+
case "Adjust":
|
|
23
|
+
return ModulesFacade.EXTERNAL_ATTRIBUTION_ADJUST;
|
|
24
|
+
case "Kochava":
|
|
25
|
+
return ModulesFacade.EXTERNAL_ATTRIBUTION_KOCHAVA;
|
|
26
|
+
case "Tenjin":
|
|
27
|
+
return ModulesFacade.EXTERNAL_ATTRIBUTION_TENJIN;
|
|
28
|
+
case "Airbridge":
|
|
29
|
+
return ModulesFacade.EXTERNAL_ATTRIBUTION_AIRBRIDGE;
|
|
30
|
+
case "Singular":
|
|
31
|
+
return ModulesFacade.EXTERNAL_ATTRIBUTION_SINGULAR;
|
|
32
|
+
default:
|
|
33
|
+
return -1;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public static String parseValue(ReadableMap valueMap) {
|
|
38
|
+
if (valueMap == null) {
|
|
39
|
+
return "";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return new JSONObject(valueMap.toHashMap()).toString();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
package io.appmetrica.analytics.reactnative;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import androidx.annotation.Nullable;
|
|
5
|
+
import com.facebook.react.bridge.Callback;
|
|
6
|
+
import com.facebook.react.bridge.WritableMap;
|
|
7
|
+
import com.facebook.react.bridge.WritableNativeMap;
|
|
8
|
+
|
|
9
|
+
import io.appmetrica.analytics.DeferredDeeplinkListener;
|
|
10
|
+
import io.appmetrica.analytics.StartupParamsCallback;
|
|
11
|
+
|
|
12
|
+
public class ReactNativeDeferredDeeplinkListener implements DeferredDeeplinkListener {
|
|
13
|
+
|
|
14
|
+
@NonNull
|
|
15
|
+
private final Callback failureListener;
|
|
16
|
+
|
|
17
|
+
@NonNull
|
|
18
|
+
private final Callback successListener;
|
|
19
|
+
|
|
20
|
+
ReactNativeDeferredDeeplinkListener(@NonNull Callback failureCallback, @NonNull Callback successCallback) {
|
|
21
|
+
this.failureListener = failureCallback;
|
|
22
|
+
this.successListener = successCallback;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@Override
|
|
26
|
+
public void onDeeplinkLoaded(@NonNull String deeplink) {
|
|
27
|
+
successListener.invoke(deeplink);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@Override
|
|
31
|
+
public void onError(@NonNull Error error, @Nullable String referrer) {
|
|
32
|
+
failureListener.invoke(getErrorStr(error), referrer);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@NonNull
|
|
36
|
+
private static String getErrorStr(@NonNull Error error) {
|
|
37
|
+
switch (error) {
|
|
38
|
+
case NO_REFERRER:
|
|
39
|
+
return "NO_REFERRER";
|
|
40
|
+
case NOT_A_FIRST_LAUNCH:
|
|
41
|
+
return "NOT_A_FIRST_LAUNCH";
|
|
42
|
+
case PARSE_ERROR:
|
|
43
|
+
return "PARSE_ERROR";
|
|
44
|
+
default:
|
|
45
|
+
return "UNKNOWN";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
package io.appmetrica.analytics.reactnative;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import com.facebook.react.bridge.Callback;
|
|
5
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
6
|
+
import com.facebook.react.bridge.WritableMap;
|
|
7
|
+
import com.facebook.react.bridge.WritableNativeMap;
|
|
8
|
+
import com.facebook.react.bridge.Arguments;
|
|
9
|
+
|
|
10
|
+
import io.appmetrica.analytics.DeferredDeeplinkListener;
|
|
11
|
+
import io.appmetrica.analytics.DeferredDeeplinkParametersListener;
|
|
12
|
+
import java.util.Map;
|
|
13
|
+
|
|
14
|
+
public class ReactNativeDeferredDeeplinkParametersListener implements DeferredDeeplinkParametersListener {
|
|
15
|
+
@NonNull
|
|
16
|
+
private final Callback failureListener;
|
|
17
|
+
|
|
18
|
+
@NonNull
|
|
19
|
+
private final Callback successListener;
|
|
20
|
+
|
|
21
|
+
ReactNativeDeferredDeeplinkParametersListener(@NonNull Callback failureCallback, @NonNull Callback successCallback) {
|
|
22
|
+
this.failureListener = failureCallback;
|
|
23
|
+
this.successListener = successCallback;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@Override
|
|
27
|
+
public void onParametersLoaded(@NonNull Map<String, String> map) {
|
|
28
|
+
WritableMap writableMap = Arguments.createMap();
|
|
29
|
+
for (Map.Entry<String, String> entry : map.entrySet()) {
|
|
30
|
+
writableMap.putString(entry.getKey(), entry.getValue());
|
|
31
|
+
}
|
|
32
|
+
successListener.invoke(writableMap, null);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Override
|
|
36
|
+
public void onError(@NonNull Error error, @NonNull String referrer) {
|
|
37
|
+
failureListener.invoke(getErrorStr(error), referrer);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@NonNull
|
|
41
|
+
private static String getErrorStr(@NonNull DeferredDeeplinkParametersListener.Error error) {
|
|
42
|
+
switch (error) {
|
|
43
|
+
case NO_REFERRER:
|
|
44
|
+
return "NO_REFERRER";
|
|
45
|
+
case NOT_A_FIRST_LAUNCH:
|
|
46
|
+
return "NOT_A_FIRST_LAUNCH";
|
|
47
|
+
case PARSE_ERROR:
|
|
48
|
+
return "PARSE_ERROR";
|
|
49
|
+
default:
|
|
50
|
+
return "UNKNOWN";
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
package io.appmetrica.analytics.reactnative;
|
|
2
|
+
|
|
3
|
+
import android.util.Log;
|
|
4
|
+
|
|
5
|
+
import androidx.annotation.NonNull;
|
|
6
|
+
|
|
7
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
8
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
9
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
10
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
11
|
+
|
|
12
|
+
import io.appmetrica.analytics.AppMetrica;
|
|
13
|
+
import io.appmetrica.analytics.ecommerce.ECommerceEvent;
|
|
14
|
+
import io.appmetrica.analytics.plugins.PluginErrorDetails;
|
|
15
|
+
|
|
16
|
+
public class ReporterModule extends ReactContextBaseJavaModule {
|
|
17
|
+
|
|
18
|
+
public static final String NAME = "AppMetricaReporter";
|
|
19
|
+
|
|
20
|
+
private static final String TAG = "ReporterModule";
|
|
21
|
+
|
|
22
|
+
@NonNull
|
|
23
|
+
private final ReactApplicationContext reactContext;
|
|
24
|
+
|
|
25
|
+
public ReporterModule(@NonNull ReactApplicationContext reactContext) {
|
|
26
|
+
super(reactContext);
|
|
27
|
+
this.reactContext = reactContext;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@NonNull
|
|
31
|
+
@Override
|
|
32
|
+
public String getName() {
|
|
33
|
+
return NAME;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@ReactMethod
|
|
37
|
+
public void reportError(String apiKey, String identifier, String message, ReadableMap _reason) {
|
|
38
|
+
PluginErrorDetails errorDetails = _reason != null ? ExceptionSerializer.fromObject(_reason) : null;
|
|
39
|
+
AppMetrica.getReporter(reactContext, apiKey).getPluginExtension().reportError(identifier, message, errorDetails);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@ReactMethod
|
|
43
|
+
public void reportErrorWithoutIdentifier(String apiKey, String message, ReadableMap error) {
|
|
44
|
+
PluginErrorDetails details = ExceptionSerializer.fromObject(error);
|
|
45
|
+
if (details.getStacktrace().isEmpty()) {
|
|
46
|
+
AppMetrica.getReporter(reactContext, apiKey).getPluginExtension().reportError("Errors without stacktrace", message, details);
|
|
47
|
+
} else {
|
|
48
|
+
AppMetrica.getReporter(reactContext, apiKey).getPluginExtension().reportError(details, message);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@ReactMethod
|
|
53
|
+
public void reportUnhandledException(String apiKey, ReadableMap error) {
|
|
54
|
+
PluginErrorDetails details = ExceptionSerializer.fromObject(error);
|
|
55
|
+
AppMetrica.getReporter(reactContext, apiKey).getPluginExtension().reportUnhandledException(details);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@ReactMethod
|
|
59
|
+
public void reportEvent(String apiKey, String eventName, ReadableMap attributes) {
|
|
60
|
+
if (attributes == null) {
|
|
61
|
+
AppMetrica.getReporter(reactContext, apiKey).reportEvent(eventName);
|
|
62
|
+
} else {
|
|
63
|
+
AppMetrica.getReporter(reactContext, apiKey).reportEvent(eventName, attributes.toHashMap());
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@ReactMethod
|
|
68
|
+
public void pauseSession(String apiKey) {
|
|
69
|
+
AppMetrica.getReporter(reactContext, apiKey).pauseSession();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@ReactMethod
|
|
73
|
+
public void resumeSession(String apiKey) {
|
|
74
|
+
AppMetrica.getReporter(reactContext, apiKey).resumeSession();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@ReactMethod
|
|
78
|
+
public void sendEventsBuffer(String apiKey) {
|
|
79
|
+
AppMetrica.getReporter(reactContext, apiKey).sendEventsBuffer();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@ReactMethod
|
|
83
|
+
public void clearAppEnvironment(String apiKey) {
|
|
84
|
+
AppMetrica.getReporter(reactContext, apiKey).clearAppEnvironment();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@ReactMethod
|
|
88
|
+
public void putAppEnvironmentValue(String apiKey, String key, String value) {
|
|
89
|
+
AppMetrica.getReporter(reactContext, apiKey).putAppEnvironmentValue(key, value);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@ReactMethod
|
|
93
|
+
public void setUserProfileID(String apiKey, String userProfileID) {
|
|
94
|
+
AppMetrica.getReporter(reactContext, apiKey).setUserProfileID(userProfileID);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@ReactMethod
|
|
98
|
+
public void reportUserProfile(String apiKey, ReadableMap userProfile) {
|
|
99
|
+
try {
|
|
100
|
+
AppMetrica.getReporter(reactContext, apiKey).reportUserProfile(Utils.toUserProfile(userProfile));
|
|
101
|
+
} catch (Throwable e) {
|
|
102
|
+
Log.w(TAG, "Cannot parse user profile", e);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@ReactMethod
|
|
107
|
+
public void setDataSendingEnabled(String apiKey, boolean enabled) {
|
|
108
|
+
AppMetrica.getReporter(reactContext, apiKey).setDataSendingEnabled(enabled);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@ReactMethod
|
|
112
|
+
public void reportAdRevenue(String apiKey, ReadableMap AdRevenueMap) {
|
|
113
|
+
AppMetrica.getReporter(reactContext, apiKey).reportAdRevenue(Utils.toAdRevenue(AdRevenueMap));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@ReactMethod
|
|
117
|
+
public void reportECommerce(String apiKey, ReadableMap ecommerceEvent) {
|
|
118
|
+
ECommerceEvent event = Utils.toECommerceEvent(ecommerceEvent);
|
|
119
|
+
if (event != null) {
|
|
120
|
+
AppMetrica.getReporter(reactContext, apiKey).reportECommerce(event);
|
|
121
|
+
} else {
|
|
122
|
+
Log.w(TAG, "ECommerceEvent is null");
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@ReactMethod
|
|
127
|
+
public void reportRevenue(String apiKey, ReadableMap revenueMap) {
|
|
128
|
+
AppMetrica.getReporter(reactContext, apiKey).reportRevenue(Utils.toRevenue(revenueMap));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -11,6 +11,7 @@ import io.appmetrica.analytics.AdRevenue;
|
|
|
11
11
|
import io.appmetrica.analytics.AdType;
|
|
12
12
|
import io.appmetrica.analytics.AppMetricaConfig;
|
|
13
13
|
import io.appmetrica.analytics.PreloadInfo;
|
|
14
|
+
import io.appmetrica.analytics.ReporterConfig;
|
|
14
15
|
import io.appmetrica.analytics.Revenue;
|
|
15
16
|
import io.appmetrica.analytics.StartupParamsCallback;
|
|
16
17
|
import io.appmetrica.analytics.profile.UserProfile;
|
|
@@ -84,6 +85,21 @@ abstract class Utils {
|
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
87
|
}
|
|
88
|
+
if (configMap.hasKey("appEnvironment")) {
|
|
89
|
+
ReadableMap appEnvironmentMap = configMap.getMap("appEnvironment");
|
|
90
|
+
if (appEnvironmentMap != null) {
|
|
91
|
+
for (Map.Entry<String, Object> entry : appEnvironmentMap.toHashMap().entrySet()) {
|
|
92
|
+
Object value = entry.getValue();
|
|
93
|
+
builder.withAppEnvironmentValue(entry.getKey(), value == null ? null : value.toString());
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (configMap.hasKey("maxReportsCount")) {
|
|
98
|
+
builder.withMaxReportsCount(configMap.getInt("maxReportsCount"));
|
|
99
|
+
}
|
|
100
|
+
if (configMap.hasKey("dispatchPeriodSeconds")) {
|
|
101
|
+
builder.withDispatchPeriodSeconds(configMap.getInt("dispatchPeriodSeconds"));
|
|
102
|
+
}
|
|
87
103
|
|
|
88
104
|
return builder.build();
|
|
89
105
|
}
|
|
@@ -473,7 +489,7 @@ abstract class Utils {
|
|
|
473
489
|
}
|
|
474
490
|
|
|
475
491
|
@Nullable
|
|
476
|
-
|
|
492
|
+
static Map<String, String> toMapOfStrings(@Nullable ReadableMap oldMap) {
|
|
477
493
|
if (oldMap == null) {
|
|
478
494
|
return null;
|
|
479
495
|
}
|
|
@@ -498,4 +514,42 @@ abstract class Utils {
|
|
|
498
514
|
}
|
|
499
515
|
return newArray;
|
|
500
516
|
}
|
|
517
|
+
|
|
518
|
+
@NonNull
|
|
519
|
+
static ReporterConfig toReporterConfig(@NonNull ReadableMap configMap) {
|
|
520
|
+
ReporterConfig.Builder builder = ReporterConfig.newConfigBuilder(Objects.requireNonNull(configMap.getString("apiKey")));
|
|
521
|
+
|
|
522
|
+
if (configMap.hasKey("logs") && Boolean.TRUE.equals(configMap.getBoolean("logs"))) {
|
|
523
|
+
builder.withLogs();
|
|
524
|
+
}
|
|
525
|
+
if (configMap.hasKey("maxReportsInDatabaseCount")) {
|
|
526
|
+
builder.withMaxReportsInDatabaseCount(configMap.getInt("maxReportsInDatabaseCount"));
|
|
527
|
+
}
|
|
528
|
+
if (configMap.hasKey("sessionTimeout")) {
|
|
529
|
+
builder.withSessionTimeout(configMap.getInt("sessionTimeout"));
|
|
530
|
+
}
|
|
531
|
+
if (configMap.hasKey("dataSendingEnabled")) {
|
|
532
|
+
builder.withDataSendingEnabled(configMap.getBoolean("dataSendingEnabled"));
|
|
533
|
+
}
|
|
534
|
+
if (configMap.hasKey("appEnvironment")) {
|
|
535
|
+
ReadableMap appMap = configMap.getMap("appEnvironment");
|
|
536
|
+
if (appMap != null) {
|
|
537
|
+
for (Map.Entry<String, Object> entry : appMap.toHashMap().entrySet()) {
|
|
538
|
+
if (entry.getValue() instanceof String) {
|
|
539
|
+
builder.withAppEnvironmentValue(entry.getKey(), entry.getValue().toString());
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
if (configMap.hasKey("dispatchPeriodSeconds")) {
|
|
545
|
+
builder.withDispatchPeriodSeconds(configMap.getInt("dispatchPeriodSeconds"));
|
|
546
|
+
}
|
|
547
|
+
if (configMap.hasKey("userProfileID")) {
|
|
548
|
+
builder.withUserProfileID(configMap.getString("userProfileID"));
|
|
549
|
+
}
|
|
550
|
+
if (configMap.hasKey("maxReportsCount")) {
|
|
551
|
+
builder.withMaxReportsCount(configMap.getInt("maxReportsCount"));
|
|
552
|
+
}
|
|
553
|
+
return builder.build();
|
|
554
|
+
}
|
|
501
555
|
}
|
|
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
|
|
|
16
16
|
|
|
17
17
|
s.source_files = "ios/**/*.{h,m,mm}"
|
|
18
18
|
|
|
19
|
-
s.dependency "AppMetricaAnalytics", "5.
|
|
19
|
+
s.dependency "AppMetricaAnalytics", "5.10.0"
|
|
20
20
|
|
|
21
21
|
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
|
|
22
22
|
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
|