Skip to content

Commit

Permalink
Merge pull request #162 from AppsFlyerSDK/releases/5.4.1
Browse files Browse the repository at this point in the history
Releases/5.4.1
  • Loading branch information
sokoloff06 authored Jul 8, 2020
2 parents 3b8031f + c1b4245 commit 89643f8
Show file tree
Hide file tree
Showing 12 changed files with 299 additions and 80 deletions.
102 changes: 102 additions & 0 deletions Docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -677,3 +677,105 @@ appsFlyer.setDeviceTrackingDisabled(true, () => {});
```
---
##### <a id="setOneLinkCustomDomains"> **`setOneLinkCustomDomains(domains, successC, errorC)`**
Set Onelink custom/branded domains<br/>
Use this API during the SDK Initialization to indicate branded domains.<br/>
For more information please refer to the [documentation](https://support.appsflyer.com/hc/en-us/articles/360002329137-Implementing-Branded-Links)
| parameter | type | description |
| ---------- |----------|------------------ |
| domains | array | Comma separated array of branded domains |
| successC | function | success callback |
| errorC | function | error callback |
*Example:*
```javascript
appsFlyer.setOneLinkCustomDomains(["click.mybrand.com"],
(res) => {
console.log(res);
}, (error) => {
console.log(error);
});
```
---
##### <a id="setResolveDeepLinkURLs"> **`setResolveDeepLinkURLs(urls, successC, errorC)`**
Set domains used by ESP when wrapping your deeplinks.<br/>
Use this API during the SDK Initialization to indicate that links from certain domains should be resolved in order to get original deeplink<br/>
For more information please refer to the [documentation](https://support.appsflyer.com/hc/en-us/articles/360001409618-Email-service-provider-challenges-with-iOS-Universal-links) <br/>
| parameter | type | description |
| ---------- |----------|------------------ |
| urls | array | Comma separated array of ESP domains requiring resolving |
| successC | function | success callback |
| errorC | function | error callback |
*Example:*
```javascript
appsFlyer.setResolveDeepLinkURLs(["click.esp-domain.com"],
(res) => {
console.log(res);
}, (error) => {
console.log(error);
});
```
---
##### <a id="performOnAppAttribution"> **`performOnAppAttribution(url, callback)`**
This function allows developers to manually re-trigger onAppOpenAttribution with a specific link (URI or URL), **without recording a new re-engagement**.<br>
This method may be required if the app needs to redirect users based on the given link, or resolve the AppsFlyer short URL while staying in the foreground/opened. This might be needed because regular onAppOpenAttribution callback is only called if the app was opened with the deep link.
| parameter | type | description |
| ---------- |----------|------------------ |
| url | string | String representing the URL that needs to be resolved/returned in the onAppOpenAttribution callback |
| callback | function | Result callback |
*Example:*
```javascript
let uriString = "sdktest://test"
appsFlyer.performOnAppAttribution(uriString, (res) => {
console.log(res);
})
```
---
##### <a id="setSharingFilterForAllPartners"> **`setSharingFilterForAllPartners()`**
Used by advertisers to exclude **all** networks/integrated partners from getting data. Learn more [here](https://support.appsflyer.com/hc/en-us/articles/207032126#additional-apis-exclude-partners-from-getting-data)
*Example:*
```javascript
appsFlyer.setSharingFilterForAllPartners()
```
---
##### <a id="setSharingFilter"> **`setSharingFilter(partners, sucessC, errorC)`**
Used by advertisers to exclude **specified** networks/integrated partners from getting data. Learn more [here](https://support.appsflyer.com/hc/en-us/articles/207032126#additional-apis-exclude-partners-from-getting-data)
| parameter | type | description |
| ---------- |----------|------------------ |
| partners | array | Comma separated array of partners that need to be excluded |
| successC | function | success callback |
| errorC | function | error callback |
*Example:*
```javascript
let partners = ["facebook_int","googleadwords_int","snapchat_int","doubleclick_int"]
appsFlyer.setSharingFilterForAllPartners(partners,
(res) => {
console.log(res);
}, (error) => {
console.log(error);
})
```
---
57 changes: 11 additions & 46 deletions Docs/Guides.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,6 @@ The `appsFlyer.onAppOpenAttribution` returns function to unregister this event
### *Example:*

```javascript
import React, {useEffect, useState} from 'react';
import {AppState, SafeAreaView, Text, View} from 'react-native';
import appsFlyer from 'react-native-appsflyer';

var onAppOpenAttributionCanceller = appsFlyer.onAppOpenAttribution((res) => {
Expand Down Expand Up @@ -148,18 +146,8 @@ appsFlyer.initSdk(
// ...

class App extends Component<{}> {
state = {
appState: AppState.currentState,
};

componentDidMount() {
AppState.addEventListener('change', this._handleAppStateChange);
}

componentWillUnmount() {
AppState.removeEventListener('change', this._handleAppStateChange);

// Optionaly remove listeners for deep link data if you no longer need them
// Optionaly remove listeners for deep link data if you no longer need them after componentWillUnmount
if (onInstallConversionDataCanceller) {
onInstallConversionDataCanceller();
console.log('unregister onInstallConversionDataCanceller');
Expand All @@ -171,15 +159,6 @@ class App extends Component<{}> {
onAppOpenAttributionCanceller = null;
}
}

_handleAppStateChange = (nextAppState) => {
if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
if (Platform.OS === 'ios') {
appsFlyer.trackAppLaunch();
}
}
this.setState({appState: nextAppState});
};
}
```

Expand Down Expand Up @@ -227,33 +206,19 @@ appsFlyer.initSdk(

const Home = (props) => {

const [appState, setAppState] = useState(AppState.currentState);

useEffect(() => {
function handleAppStateChange(nextAppState) {
if (appState.match(/inactive|background/) && nextAppState === 'active') {
if (Platform.OS === 'ios') {
appsFlyer.trackAppLaunch();
}
return () => {
// Optionaly remove listeners for deep link data if you no longer need them after componentWillUnmount
if (onInstallConversionDataCanceller) {
onInstallConversionDataCanceller();
console.log('unregister onInstallConversionDataCanceller');
onInstallConversionDataCanceller = null;
}
if (appState.match(/active|foreground/) && nextAppState === 'background') {
if (onInstallConversionDataCanceller) {
onInstallConversionDataCanceller();
onInstallConversionDataCanceller = null;
}
if (onAppOpenAttributionCanceller) {
onAppOpenAttributionCanceller();
onAppOpenAttributionCanceller = null;
}
if (onAppOpenAttributionCanceller) {
onAppOpenAttributionCanceller();
console.log('unregister onAppOpenAttributionCanceller');
onAppOpenAttributionCanceller = null;
}

setAppState(nextAppState);
}

AppState.addEventListener('change', handleAppStateChange);

return () => {
AppState.removeEventListener('change', handleAppStateChange);
};
});

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@

### <a id="plugin-build-for"> This plugin is built for

- iOS AppsFlyerSDK **v5.2.0**
- Android AppsFlyerSDK **v5.2.0**
- iOS AppsFlyerSDK **v5.4.1**
- Android AppsFlyerSDK **v5.4.1**


## <a id="installation"> 📲 Adding the SDK to your project
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ repositories {
dependencies {
implementation "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
implementation "com.android.installreferrer:installreferrer:${safeExtGet('installReferrerVersion', '1.0')}"
implementation "com.appsflyer:af-android-sdk:${safeExtGet('appsflyerVersion', '5.2.0')}"
implementation "com.appsflyer:af-android-sdk:${safeExtGet('appsflyerVersion', '5.4.1')}"
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ public class RNAppsFlyerConstants {
final static String UNKNOWN_ERROR = "AF Unknown Error";
final static String SUCCESS = "Success";
final static String NO_EVENT_NAME_FOUND = "No 'eventName' found or its empty";
final static String NO_EMAILS_FOUND_OR_CORRUPTED = "No 'emails' found, or list is corrupted";
final static String EMPTY_OR_CORRUPTED_LIST = "No arguments found or list is corrupted";
final static String INVALID_URI = "Passed string is not a valid URI";


final static String afIsDebug = "isDebug";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.modules.core.DeviceEventManagerModule;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import java.util.ArrayList;

import static com.appsflyer.reactnative.RNAppsFlyerConstants.*;

Expand Down Expand Up @@ -135,18 +138,14 @@ private String callSdkInternal(ReadableMap _options) {
Activity currentActivity = getCurrentActivity();

if (currentActivity != null) {
intent = currentActivity.getIntent();
// register for lifecycle with Activity (automatically fetching deeplink from Activity if present)
instance.startTracking(currentActivity, devKey);
} else {
// register for lifecycle with Application (cannot fetch deeplink without access to the Activity,
// also sending first session manually)
trackAppLaunch();
instance.startTracking(application, devKey);
}

//Generally we already do this validation into the SDK, anyways, we want to show it to clients
if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) {
AppsFlyerLib.getInstance().setPluginDeepLinkData(intent);
}

trackAppLaunch();
instance.startTracking(application, devKey);


return null;
}

Expand Down Expand Up @@ -402,7 +401,7 @@ public void setUserEmails(ReadableMap _options,
JSONArray emailsJSON = options.optJSONArray(afEmails);

if (emailsJSON.length() == 0) {
errorCallback.invoke(new Exception(NO_EMAILS_FOUND_OR_CORRUPTED).getMessage());
errorCallback.invoke(new Exception(EMPTY_OR_CORRUPTED_LIST).getMessage());
return;
}

Expand All @@ -422,7 +421,7 @@ public void setUserEmails(ReadableMap _options,
}
} catch (JSONException e) {
e.printStackTrace();
errorCallback.invoke(new Exception(NO_EMAILS_FOUND_OR_CORRUPTED).getMessage());
errorCallback.invoke(new Exception(EMPTY_OR_CORRUPTED_LIST).getMessage());
return;
}

Expand Down Expand Up @@ -562,4 +561,73 @@ public void setDeviceTrackingDisabled(boolean b, Callback callback){
AppsFlyerLib.getInstance().setDeviceTrackingDisabled(b);
callback.invoke(SUCCESS);
}

@ReactMethod
public void setOneLinkCustomDomains(ReadableArray domainsArray, Callback successCallback, Callback errorCallback) {
if (domainsArray.size() <= 0) {
errorCallback.invoke(EMPTY_OR_CORRUPTED_LIST);
return;
}
ArrayList<Object> domainsList = domainsArray.toArrayList();
try {
String[] domains = domainsList.toArray(new String[domainsList.size()]);
AppsFlyerLib.getInstance().setOneLinkCustomDomain(domains);
successCallback.invoke(SUCCESS);
} catch (Exception e) {
e.printStackTrace();
errorCallback.invoke(EMPTY_OR_CORRUPTED_LIST);
}
}

@ReactMethod
public void setResolveDeepLinkURLs(ReadableArray urlsArray, Callback successCallback, Callback errorCallback) {
if (urlsArray.size() <= 0) {
errorCallback.invoke(EMPTY_OR_CORRUPTED_LIST);
return;
}
ArrayList<Object> urlsList = urlsArray.toArrayList();
try {
String[] urls = urlsList.toArray(new String[urlsList.size()]);
AppsFlyerLib.getInstance().setResolveDeepLinkURLs(urls);
successCallback.invoke(SUCCESS);
} catch (Exception e) {
e.printStackTrace();
errorCallback.invoke(EMPTY_OR_CORRUPTED_LIST);
}
}

@ReactMethod
public void performOnAppAttribution(String urlString, Callback callback) {
try {
URI uri = URI.create(urlString);
Context c = application.getApplicationContext();
AppsFlyerLib.getInstance().performOnAppAttribution(c, uri);
callback.invoke(SUCCESS);
} catch (Exception e) {
e.printStackTrace();
callback.invoke(INVALID_URI);
}
}

@ReactMethod
public void setSharingFilterForAllPartners() {
AppsFlyerLib.getInstance().setSharingFilterForAllPartners();
}

@ReactMethod
public void setSharingFilter(ReadableArray partnersArray, Callback successCallback, Callback errorCallback) {
if (partnersArray.size() <= 0) {
errorCallback.invoke(EMPTY_OR_CORRUPTED_LIST);
return;
}
ArrayList<Object> partnersList = partnersArray.toArrayList();
try {
String[] partners = partnersList.toArray(new String[partnersList.size()]);
AppsFlyerLib.getInstance().setSharingFilter(partners);
successCallback.invoke(SUCCESS);
} catch (Exception e) {
e.printStackTrace();
errorCallback.invoke(EMPTY_OR_CORRUPTED_LIST);
}
}
}
27 changes: 16 additions & 11 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,27 @@ declare module "react-native-appsflyer" {
initSdk(options:InitSDKOptions, successC?:SuccessCB, errorC?:ErrorCB): Response<string>
trackEvent(eventName:string, eventValues:object, successC?:SuccessCB, errorC?:ErrorCB): Response<string>
setUserEmails(options:SetEmailsOptions, successC?:SuccessCB, errorC?:ErrorCB): void
setAdditionalData(additionalData:object, successC?:SuccessCB): void
getAppsFlyerUID(callback:(error:Error, uid:string)=>any): void
setCustomerUserId(userId:string, successC?:SuccessCB): void
stopTracking(isStopTracking:boolean, successC?:SuccessCB): void
setAppInviteOneLinkID(oneLinkID:string, successC?:SuccessCB): void
generateInviteLink(params:GenerateInviteLinkParams, successC?:SuccessCB, errorC?:ErrorCB): void
trackCrossPromotionImpression(appId:string, campaign:string): void
trackAndOpenStore(appId:string, campaign:string, params: object): void
setCurrencyCode(currencyCode:string, successC:SuccessCB): void
setDeviceTrackingDisabled(isDeviceTrackingDisabled:boolean, successC:SuccessCB): void
setAdditionalData(additionalData: object, successC?: SuccessCB): void
getAppsFlyerUID(callback: (error: Error, uid: string) => any): void
setCustomerUserId(userId: string, successC?: SuccessCB): void
stopTracking(isStopTracking: boolean, successC?: SuccessCB): void
setAppInviteOneLinkID(oneLinkID: string, successC?: SuccessCB): void
generateInviteLink(params: GenerateInviteLinkParams, successC?: SuccessCB, errorC?: ErrorCB): void
trackCrossPromotionImpression(appId: string, campaign: string): void
trackAndOpenStore(appId: string, campaign: string, params: object): void
setCurrencyCode(currencyCode: string, successC: SuccessCB): void
setDeviceTrackingDisabled(isDeviceTrackingDisabled: boolean, successC: SuccessCB): void
setOneLinkCustomDomains(domains: string[], successC?: SuccessCB, errorC?: ErrorCB): void
setResolveDeepLinkURLs(urls: string[], successC?: SuccessCB, errorC?: ErrorCB): void
performOnAppAttribution(urlString, callback): void
setSharingFilterForAllPartners(): void
setSharingFilter(partners, successC, errorC): void

/**
* For iOS Only
* */
trackAppLaunch(): void
trackLocation(longitude:number, latitude:number, callback:SuccessCB): void
trackLocation(longitude: number, latitude: number, callback: SuccessCB): void

/**
* For Android Only
Expand Down
Loading

0 comments on commit 89643f8

Please sign in to comment.