@appmetrica/react-native-analytics 3.3.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 +60 -6
- 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 +16 -9
- 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 +77 -7
- 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/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/index.js +53 -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/index.js +42 -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/index.d.ts +19 -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/index.ts +79 -2
- 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
|
}
|
|
@@ -19,6 +19,7 @@ import io.appmetrica.analytics.AppMetrica;
|
|
|
19
19
|
import io.appmetrica.analytics.AppMetricaConfig;
|
|
20
20
|
import io.appmetrica.analytics.ModulesFacade;
|
|
21
21
|
import io.appmetrica.analytics.ecommerce.ECommerceEvent;
|
|
22
|
+
import io.appmetrica.analytics.plugins.PluginErrorDetails;
|
|
22
23
|
|
|
23
24
|
@ReactModule(name = AppMetricaModule.NAME)
|
|
24
25
|
public class AppMetricaModule extends ReactContextBaseJavaModule {
|
|
@@ -70,12 +71,9 @@ public class AppMetricaModule extends ReactContextBaseJavaModule {
|
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
@ReactMethod
|
|
73
|
-
public void reportError(String identifier, String message) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
} catch (Throwable error) {
|
|
77
|
-
AppMetrica.reportError(identifier, message, error);
|
|
78
|
-
}
|
|
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);
|
|
79
77
|
}
|
|
80
78
|
|
|
81
79
|
@ReactMethod
|
|
@@ -156,6 +154,22 @@ public class AppMetricaModule extends ReactContextBaseJavaModule {
|
|
|
156
154
|
AppMetrica.putErrorEnvironmentValue(key, value);
|
|
157
155
|
}
|
|
158
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
|
+
|
|
159
173
|
@ReactMethod
|
|
160
174
|
public void reportExternalAttribution(ReadableMap attribution) {
|
|
161
175
|
ModulesFacade.reportExternalAttribution(
|
|
@@ -163,4 +177,44 @@ public class AppMetricaModule extends ReactContextBaseJavaModule {
|
|
|
163
177
|
ExternalAttributionSerializer.parseValue(attribution.getMap("value"))
|
|
164
178
|
);
|
|
165
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
|
+
}
|
|
166
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
CHANGED
|
@@ -16,15 +16,22 @@ final class ExternalAttributionSerializer {
|
|
|
16
16
|
return -1;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
case "AppsFlyer"
|
|
21
|
-
|
|
22
|
-
case "
|
|
23
|
-
|
|
24
|
-
case "
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
+
}
|
|
28
35
|
}
|
|
29
36
|
|
|
30
37
|
public static String parseValue(ReadableMap valueMap) {
|
|
@@ -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.
|
package/ios/AMARNAppMetrica.m
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#import "AMARNUserProfileSerializer.h"
|
|
6
6
|
#import "AMARNExternalAttribution.h"
|
|
7
7
|
#import <AppMetricaCrashes/AppMetricaCrashes.h>
|
|
8
|
+
#import "AMARNExceptionSerializer.h"
|
|
8
9
|
|
|
9
10
|
@implementation AMARNAppMetrica
|
|
10
11
|
|
|
@@ -38,9 +39,13 @@ RCT_EXPORT_METHOD(reportAppOpen:(NSString *)deeplink)
|
|
|
38
39
|
[AMAAppMetrica trackOpeningURL:[NSURL URLWithString:deeplink]];
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
RCT_EXPORT_METHOD(reportError:(NSString *)identifier:(NSString *)message) {
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
RCT_EXPORT_METHOD(reportError:(NSString *)identifier:(NSString *)message:(NSDictionary *)_reason) {
|
|
43
|
+
[[[AMAAppMetricaCrashes crashes] pluginExtension] reportErrorWithIdentifier:identifier
|
|
44
|
+
message:message
|
|
45
|
+
details:amarn_exceptionForDictionary(_reason)
|
|
46
|
+
onFailure:^(NSError *error) {
|
|
47
|
+
NSLog(@"Failed to report error to AppMetrica: %@", [error localizedDescription]);
|
|
48
|
+
}];
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
RCT_EXPORT_METHOD(reportEvent:(NSString *)eventName:(NSDictionary *)attributes)
|
|
@@ -93,7 +98,7 @@ RCT_EXPORT_METHOD(setDataSendingEnabled:(BOOL)enabled)
|
|
|
93
98
|
|
|
94
99
|
RCT_EXPORT_METHOD(reportECommerce:(NSDictionary *)ecommerceDict)
|
|
95
100
|
{
|
|
96
|
-
|
|
101
|
+
[AMAAppMetrica reportECommerce:[AMARNAppMetricaUtils ecommerceForDict:ecommerceDict] onFailure:nil];
|
|
97
102
|
}
|
|
98
103
|
|
|
99
104
|
RCT_EXPORT_METHOD(setUserProfileID:(NSString *)userProfileID)
|
|
@@ -123,21 +128,86 @@ RCT_EXPORT_METHOD(putErrorEnvironmentValue:(NSString *)key:(NSString *)value)
|
|
|
123
128
|
|
|
124
129
|
RCT_EXPORT_METHOD(reportExternalAttribution:(NSDictionary *)externalAttributionsDict)
|
|
125
130
|
{
|
|
126
|
-
|
|
131
|
+
|
|
127
132
|
NSString *sourceStr = externalAttributionsDict[@"source"];
|
|
128
133
|
AMAAttributionSource source = amarn_getExternalAttributionSource(sourceStr);
|
|
129
134
|
if (source == nil) {
|
|
130
135
|
NSLog(@"Failed to report external attribution to AppMetrica. Unknown source %@", sourceStr);
|
|
131
136
|
return;
|
|
132
137
|
}
|
|
133
|
-
|
|
138
|
+
|
|
134
139
|
NSDictionary *value = externalAttributionsDict[@"value"];
|
|
135
|
-
|
|
140
|
+
|
|
136
141
|
[AMAAppMetrica reportExternalAttribution:value source:source onFailure:^(NSError *error) {
|
|
137
142
|
NSLog(@"Failed to report external attribution to AppMetrica: %@", [error localizedDescription]);
|
|
138
143
|
}];
|
|
139
144
|
}
|
|
140
145
|
|
|
146
|
+
RCT_EXPORT_METHOD(reportErrorWithoutIdentifier:(NSString *)message:(NSDictionary *)error)
|
|
147
|
+
{
|
|
148
|
+
AMAPluginErrorDetails *details = amarn_exceptionForDictionary(error);
|
|
149
|
+
if (details.backtrace.count == 0) {
|
|
150
|
+
[[[AMAAppMetricaCrashes crashes] pluginExtension] reportErrorWithIdentifier:@"Errors without stacktrace"
|
|
151
|
+
message:message
|
|
152
|
+
details:details
|
|
153
|
+
onFailure:^(NSError *error) {
|
|
154
|
+
NSLog(@"Failed to report error to AppMetrica: %@", [error localizedDescription]);
|
|
155
|
+
}];
|
|
156
|
+
} else {
|
|
157
|
+
[[[AMAAppMetricaCrashes crashes] pluginExtension] reportError:details message:message onFailure:^(NSError *error) {
|
|
158
|
+
NSLog(@"Failed to report error to AppMetrica: %@", [error localizedDescription]);
|
|
159
|
+
}];
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
RCT_EXPORT_METHOD(reportUnhandledException:(NSDictionary *)error)
|
|
164
|
+
{
|
|
165
|
+
[[[AMAAppMetricaCrashes crashes] pluginExtension] reportUnhandledException:amarn_exceptionForDictionary(error)
|
|
166
|
+
onFailure:^(NSError *error) {
|
|
167
|
+
NSLog(@"Failed to report unhandled exception to AppMetrica: %@", [error localizedDescription]);
|
|
168
|
+
}];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
RCT_EXPORT_METHOD(putAppEnvironmentValue:(NSString *)key:(NSString *)value)
|
|
172
|
+
{
|
|
173
|
+
[AMAAppMetrica setAppEnvironmentValue:value forKey:key];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
RCT_EXPORT_METHOD(clearAppEnvironment)
|
|
177
|
+
{
|
|
178
|
+
[AMAAppMetrica clearAppEnvironment];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
RCT_EXPORT_METHOD(activateReporter:(NSDictionary *)configDict)
|
|
182
|
+
{
|
|
183
|
+
[AMAAppMetrica activateReporterWithConfiguration:[AMARNAppMetricaUtils reporterConfigurationForDictionary:configDict]];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
RCT_EXPORT_METHOD(touchReporter:(NSString *)apiKey)
|
|
187
|
+
{
|
|
188
|
+
[AMAAppMetrica reporterForAPIKey:apiKey];
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
RCT_EXPORT_METHOD(getDeviceId:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
192
|
+
{
|
|
193
|
+
resolve([AMAAppMetrica deviceID]);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
RCT_EXPORT_METHOD(getUuid:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
197
|
+
{
|
|
198
|
+
resolve([AMAAppMetrica UUID]);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
RCT_EXPORT_METHOD(requestDeferredDeeplink:(RCTResponseSenderBlock)onFailure:(RCTResponseSenderBlock)onSuccess)
|
|
202
|
+
{
|
|
203
|
+
// It does nothing for iOS
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
RCT_EXPORT_METHOD(requestDeferredDeeplinkParameters:(RCTResponseSenderBlock)onFailure:(RCTResponseSenderBlock)onSuccess)
|
|
207
|
+
{
|
|
208
|
+
// It does nothing for iOS
|
|
209
|
+
}
|
|
210
|
+
|
|
141
211
|
- (NSObject *)wrap:(NSObject *)value
|
|
142
212
|
{
|
|
143
213
|
if (value == nil) {
|