Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# react-native-appmetrica
# forked-react-native-appmetrica
React Native bridge to the [AppMetrica](https://appmetrica.yandex.com/) on both iOS and Android.

## Installation

1. `npm install react-native-appmetrica --save`
1. `npm install forked-react-native-appmetrica --save`
2. If React Native version <= 0.59: \
`react-native link react-native-appmetrica`
`react-native link forked-react-native-appmetrica`
3. iOS only
* if `${PROJECT_DIR}/ios/Podfile` exists: \
`npx pod-install`
Expand All @@ -15,7 +15,7 @@ React Native bridge to the [AppMetrica](https://appmetrica.yandex.com/) on both
## Usage

```js
import AppMetrica from 'react-native-appmetrica';
import AppMetrica from 'forked-react-native-appmetrica';

// Starts the statistics collection process.
AppMetrica.activate({
Expand Down
52 changes: 29 additions & 23 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@
// original location:
// - https://github.com/facebook/react-native/blob/0.58-stable/local-cli/templates/HelloWorld/android/app/build.gradle

def DEFAULT_COMPILE_SDK_VERSION = 28
def DEFAULT_BUILD_TOOLS_VERSION = '28.0.3'
def DEFAULT_MIN_SDK_VERSION = 16
def DEFAULT_TARGET_SDK_VERSION = 28
def DEFAULT_COMPILE_SDK_VERSION = 30
def DEFAULT_BUILD_TOOLS_VERSION = '30.0.2'
def DEFAULT_MIN_SDK_VERSION = 21
def DEFAULT_TARGET_SDK_VERSION = 30

def safeExtGet(prop, fallback) {
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}

apply plugin: 'com.android.library'
apply plugin: 'maven'
apply plugin: 'maven-publish'

buildscript {
// The Android Gradle plugin is only required when opening the android folder stand-alone.
Expand All @@ -39,15 +39,16 @@ buildscript {
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
classpath 'com.android.tools.build:gradle:3.6.4'
}
}
}

apply plugin: 'com.android.library'
apply plugin: 'maven'
apply plugin: 'maven-publish'

android {
compileSdkVersion safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
Expand All @@ -64,25 +65,29 @@ android {
}

repositories {
// ref: https://www.baeldung.com/maven-local-repository
mavenLocal()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
url("$rootDir/../node_modules/react-native/android")
}
maven {
// Android JSC is installed from npm
url "$rootDir/../node_modules/jsc-android/dist"
url("$rootDir/../node_modules/jsc-android/dist")
}
mavenCentral {
// We don't want to fetch react-native from Maven Central as there are
// older versions over there.
content {
excludeGroup "com.facebook.react"
}
}
google()
jcenter()
}

dependencies {
//noinspection GradleDynamicVersion
implementation 'com.facebook.react:react-native:+' // From node_modules
implementation 'com.yandex.android:mobmetricalib:3.13.3'
implementation 'com.android.installreferrer:installreferrer:1.1.2'
implementation 'com.yandex.android:mobmetricalib:5.0.1'
implementation 'com.android.installreferrer:installreferrer:2.2'
}

def configureReactNativePom(def pom) {
Expand Down Expand Up @@ -119,17 +124,19 @@ afterEvaluate { project ->
task androidJavadoc(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += files(android.bootClasspath)
classpath += files(project.getConfigurations().getByName('compile').asList())
project.getConfigurations().getByName('implementation').setCanBeResolved(true)
// To do понять почему не компилит с этой сторокой и нужна ли она вообще.
// classpath += files(project.getConfigurations().getByName('implementation').asList())
include '**/*.java'
}

task androidJavadocJar(type: Jar, dependsOn: androidJavadoc) {
classifier = 'javadoc'
archiveClassifier = 'javadoc'
from androidJavadoc.destinationDir
}

task androidSourcesJar(type: Jar) {
classifier = 'sources'
archiveClassifier = 'sources'
from android.sourceSets.main.java.srcDirs
include '**/*.java'
}
Expand All @@ -148,12 +155,11 @@ afterEvaluate { project ->
archives androidJavadocJar
}

task installArchives(type: Upload) {
configuration = configurations.archives
repositories.mavenDeployer {
// Deploy to react-native-event-bridge/maven, ready to publish to npm
repository url: "file://${projectDir}/../android/maven"
configureReactNativePom pom
publishing {
repositories {
maven {
url = uri("${rootProject.projectDir}/maven-repo")
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,21 @@
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.yandex.metrica.YandexMetrica;
import com.yandex.metrica.ecommerce.ECommerceAmount;
import com.yandex.metrica.ecommerce.ECommerceCartItem;
import com.yandex.metrica.ecommerce.ECommerceEvent;
import com.yandex.metrica.ecommerce.ECommerceOrder;
import com.yandex.metrica.ecommerce.ECommercePrice;
import com.yandex.metrica.ecommerce.ECommerceProduct;
import com.yandex.metrica.ecommerce.ECommerceReferrer;
import com.yandex.metrica.ecommerce.ECommerceScreen;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class AppMetricaModule extends ReactContextBaseJavaModule {

Expand Down Expand Up @@ -127,4 +140,112 @@ public void setStatisticsSending(boolean enabled) {
public void setUserProfileID(String userProfileID) {
YandexMetrica.setUserProfileID(userProfileID);
}

///// E-commerce

public ECommerceScreen createScreen(ReadableMap params) {
if (params == null) return null;
return new ECommerceScreen()
.setName(params.getString("name"))
.setCategoriesPath(Utils.toListString(params.getArray("categoryComponents")))
.setSearchQuery(params.getString("searchQuery"))
.setPayload(Utils.toMapString(params.getMap("payload")));
}

public ECommerceReferrer createReferrer(ReadableMap params) {
if (params == null) return null;
ECommerceScreen screen = this.createScreen(params.getMap("screen"));
return new ECommerceReferrer()
.setType(params.getString("type"))
.setIdentifier(params.getString("identifier"))
.setScreen(screen);
}

public ECommercePrice createPrice(ReadableMap params) {
if (params == null) return null;
ReadableMap fiatMap = params.getMap("fiat");
ECommerceAmount fiat = new ECommerceAmount(fiatMap.getDouble("value"), fiatMap.getString("currency"));
// TODO: internalComponents
return new ECommercePrice(fiat);
}

public ECommerceProduct createProduct(ReadableMap params) {
return new ECommerceProduct(params.getString("sku"))
.setName(params.getString("name"))
.setCategoriesPath(Utils.toListString(params.getArray("categoryComponents")))
.setPayload(Utils.toMapString(params.getMap("payload")))
.setActualPrice(this.createPrice(params.getMap("actualPrice")))
.setOriginalPrice(this.createPrice(params.getMap("originalPrice")))
.setPromocodes(Utils.toListString(params.getArray("promoCodes")));
}

public ECommerceCartItem createCartItem(ReadableMap params) {
ECommerceProduct product = this.createProduct(params.getMap("product"));
ECommercePrice revenue = this.createPrice(params.getMap("revenue"));
ECommerceReferrer referrer = this.createReferrer(params.getMap("referrer"));

return new ECommerceCartItem(product, revenue, params.getInt("quantity"))
.setReferrer(referrer);
}

@ReactMethod
public void showScreen(ReadableMap screenParams) {
ECommerceScreen screen = this.createScreen(screenParams);
ECommerceEvent showScreenEvent = ECommerceEvent.showScreenEvent(screen);
YandexMetrica.reportECommerce(showScreenEvent);
}

@ReactMethod
public void showProductCard(ReadableMap productParams, ReadableMap screenParams) {
ECommerceProduct product = this.createProduct(productParams);
ECommerceScreen screen = this.createScreen(screenParams);
ECommerceEvent showProductCardEvent = ECommerceEvent.showProductCardEvent(product, screen);
YandexMetrica.reportECommerce(showProductCardEvent);
}

@ReactMethod
public void showProductDetails(ReadableMap productParams, ReadableMap referrerParams) {
ECommerceProduct product = this.createProduct(productParams);
ECommerceReferrer referrer = this.createReferrer(referrerParams);
ECommerceEvent showProductDetailsEvent = ECommerceEvent.showProductDetailsEvent(product, referrer);
YandexMetrica.reportECommerce(showProductDetailsEvent);
}

@ReactMethod
public void addToCart(ReadableMap cartItemParams) {
ECommerceCartItem cartItem = this.createCartItem(cartItemParams);
ECommerceEvent addCartItemEvent = ECommerceEvent.addCartItemEvent(cartItem);
YandexMetrica.reportECommerce(addCartItemEvent);
}

@ReactMethod
public void removeFromCart(ReadableMap params) {
ECommerceCartItem cartItem = this.createCartItem(params);
ECommerceEvent removeCartItemEvent = ECommerceEvent.removeCartItemEvent(cartItem);
YandexMetrica.reportECommerce(removeCartItemEvent);
}

@ReactMethod
public void beginCheckout(ReadableArray cartItems, String identifier, ReadableMap payload) {
ArrayList<ECommerceCartItem> cartItemsObj = new ArrayList<>();
for (int i = 0; i < cartItemsObj.size(); i++) {
cartItemsObj.add(this.createCartItem(cartItems.getMap(i)));
}
ECommerceOrder order = new ECommerceOrder(identifier, cartItemsObj)
.setPayload(Utils.toMapString(payload));
ECommerceEvent beginCheckoutEvent = ECommerceEvent.beginCheckoutEvent(order);
YandexMetrica.reportECommerce(beginCheckoutEvent);
}

@ReactMethod
public void purchase(ReadableArray cartItems, String identifier, ReadableMap payload) {
ArrayList<ECommerceCartItem> cartItemsObj = new ArrayList<>();
for (int i = 0; i < cartItemsObj.size(); i++) {
cartItemsObj.add(this.createCartItem(cartItems.getMap(i)));
}
ECommerceOrder order = new ECommerceOrder(identifier, cartItemsObj)
.setPayload(Utils.toMapString(payload));
ECommerceEvent purchaseEvent = ECommerceEvent.purchaseEvent(order);
YandexMetrica.reportECommerce(purchaseEvent);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,18 @@

import android.location.Location;

import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.yandex.metrica.PreloadInfo;
import com.yandex.metrica.YandexMetricaConfig;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

abstract class Utils {

Expand All @@ -31,9 +37,6 @@ static YandexMetricaConfig toYandexMetricaConfig(ReadableMap configMap) {
if (configMap.hasKey("firstActivationAsUpdate")) {
builder.handleFirstActivationAsUpdate(configMap.getBoolean("firstActivationAsUpdate"));
}
if (configMap.hasKey("installedAppCollecting")) {
builder.withInstalledAppCollecting(configMap.getBoolean("installedAppCollecting"));
}
if (configMap.hasKey("location")) {
builder.withLocation(toLocation(configMap.getMap("location")));
}
Expand Down Expand Up @@ -113,4 +116,26 @@ private static PreloadInfo toPreloadInfo(ReadableMap preloadInfoMap) {

return builder.build();
}

static List<String> toListString(ReadableArray readableArray) {
if (readableArray == null) return null;
ArrayList<Object> list = readableArray.toArrayList();
List<String> strings = new ArrayList<>(list.size());
for (Object object : list) {
strings.add(Objects.toString(object, null));
}
return strings;
}

static Map<String, String> toMapString(ReadableMap readableMap) {
if (readableMap == null) return null;
Map<String, Object> map = readableMap.toHashMap();
Map<String, String> newMap = new HashMap<String, String>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getValue() instanceof String) {
newMap.put(entry.getKey(), (String) entry.getValue());
}
}
return newMap;
}
}
Loading