Skip to content

Commit

Permalink
Merge pull request #300 from AppsFlyerSDK/dev/DELIVERY-54538/DMA_update
Browse files Browse the repository at this point in the history
DMA Update
  • Loading branch information
al-af authored Feb 18, 2024
2 parents e8c4f04 + 7593539 commit 080ebbe
Show file tree
Hide file tree
Showing 59 changed files with 717 additions and 522 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

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

- Android AppsFlyer SDK **v6.12.2**
- iOS AppsFlyer SDK **v6.12.2**
- Android AppsFlyer SDK **v6.13.0**
- iOS AppsFlyer SDK **v6.13.0**

## <a id="breaking-changes"> ❗❗ Breaking changes when updating to v6.x.x❗❗

Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.appsflyer:af-android-sdk:6.12.2'
implementation 'com.appsflyer:af-android-sdk:6.13.0'
implementation 'com.android.installreferrer:installreferrer:2.1'
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.appsflyer.appsflyersdk;

public class AppsFlyerConstants {
final static String PLUGIN_VERSION = "6.12.2";
final static String PLUGIN_VERSION = "6.13.0";
final static String AF_APP_INVITE_ONE_LINK = "appInviteOneLink";
final static String AF_HOST_PREFIX = "hostPrefix";
final static String AF_HOST_NAME = "hostName";
final static String AF_IS_DEBUG = "isDebug";
final static String AF_MANUAL_START = "manualStart";
final static String AF_DEV_KEY = "afDevKey";
final static String AF_EVENT_NAME = "eventName";
final static String AF_EVENT_VALUES = "eventValues";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import android.util.Log;

import com.appsflyer.AFLogger;
import com.appsflyer.AppsFlyerConsent;
import com.appsflyer.AppsFlyerConversionListener;
import com.appsflyer.AppsFlyerInAppPurchaseValidatorListener;
import com.appsflyer.AppsFlyerLib;
Expand Down Expand Up @@ -208,6 +209,9 @@ public void onMethodCall(MethodCall call, Result result) {
case "initSdk":
initSdk(call, result);
break;
case "startSDK":
startSDK(call, result);
break;
case "logEvent":
logEvent(call, result);
break;
Expand All @@ -217,6 +221,12 @@ public void onMethodCall(MethodCall call, Result result) {
case "setCurrencyCode":
setCurrencyCode(call, result);
break;
case "enableTCFDataCollection":
enableTCFDataCollection(call, result);
break;
case "setConsentData":
setConsentData(call, result);
break;
case "setIsUpdate":
setIsUpdate(call, result);
break;
Expand Down Expand Up @@ -330,7 +340,38 @@ public void onMethodCall(MethodCall call, Result result) {
break;
}
}


private void startSDK(MethodCall call, Result result) {
AppsFlyerLib instance = AppsFlyerLib.getInstance();
instance.start(activity);
}

public void setConsentData(MethodCall call, Result result) {
Map<String, Object> arguments = (Map<String, Object>) call.arguments;
Map<String, Object> consentDict = (Map<String, Object>) arguments.get("consentData");

boolean isUserSubjectToGDPR = (boolean) consentDict.get("isUserSubjectToGDPR");
Boolean hasConsentForDataUsage = (Boolean) consentDict.get("hasConsentForDataUsage");
Boolean hasConsentForAdsPersonalization = (Boolean) consentDict.get("hasConsentForAdsPersonalization");

AppsFlyerConsent consentData;
if (isUserSubjectToGDPR && hasConsentForDataUsage != null && hasConsentForAdsPersonalization != null) {
consentData = AppsFlyerConsent.forGDPRUser(hasConsentForDataUsage, hasConsentForAdsPersonalization);
} else {
consentData = AppsFlyerConsent.forNonGDPRUser();
}

AppsFlyerLib.getInstance().setConsentData(consentData);


result.success(null);
}
private void enableTCFDataCollection(MethodCall call, Result result) {
boolean shouldCollect = (boolean) call.argument("shouldCollect");
AppsFlyerLib.getInstance().enableTCFDataCollection(shouldCollect);
result.success(null);
}

private void addPushNotificationDeepLinkPath(MethodCall call, Result result) {
if(call.arguments != null){
ArrayList<String> depplinkPath = (ArrayList<String>) call.arguments;
Expand Down Expand Up @@ -776,6 +817,8 @@ private void initSdk(MethodCall call, final MethodChannel.Result result) {
DeepLinkListener udlListener = null;
AppsFlyerLib instance = AppsFlyerLib.getInstance();

boolean isManualStartMode = (boolean) call.argument(AppsFlyerConstants.AF_MANUAL_START);

String afDevKey = (String) call.argument(AppsFlyerConstants.AF_DEV_KEY);
if (afDevKey == null || afDevKey.equals("")) {
result.error(null, "AF Dev Key is empty", "AF dev key cannot be empty");
Expand Down Expand Up @@ -814,7 +857,9 @@ private void initSdk(MethodCall call, final MethodChannel.Result result) {
instance.setAppInviteOneLink(appInviteOneLink);
}

instance.start(activity);
if (!isManualStartMode) {
instance.start(activity);
}

if (saveCallbacks) {
saveCallbacks = false;
Expand Down
89 changes: 86 additions & 3 deletions doc/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

## Methods
- [initSdk](#initSdk)
- [startSDK](#startSDK)
- [onAppOpenAttribution](#onAppOpenAttribution)
- [onInstallConversionData](#onInstallConversionData)
- [onDeepLinking](#onDeepLinking)
Expand Down Expand Up @@ -37,6 +38,8 @@
- [addPushNotificationDeepLinkPath](#addPushNotificationDeepLinkPath)
- [User Invite](#userInvite)
- [enableFacebookDeferredApplinks](#enableFacebookDeferredApplinks)
- [enableTCFDataCollection](#enableTCFDataCollection) <!-- New addition -->
- [setConsentData](#setConsentData)
- [disableSKAdNetwork](#disableSKAdNetwork)
- [getAppsFlyerUID](#getAppsFlyerUID)
- [setCurrentDeviceLanguage](#setCurrentDeviceLanguage)
Expand Down Expand Up @@ -64,11 +67,13 @@
| -------- | -------- | ------------- |
| devKey | String | Your application's [devKey](https://support.appsflyer.com/hc/en-us/articles/207032066-Basic-SDK-integration-guide#retrieving-the-dev-key) provided by AppsFlyer (required) |
| appId | String | Your application's [App ID](https://support.appsflyer.com/hc/en-us/articles/207377436-Adding-a-new-app#available-in-the-app-store-google-play-store-windows-phone-store) (required for iOS only) that you configured in your AppsFlyer dashboard |
| showDebug | bool | Debug mode - set to `true` for testing only, do not release to production with this parameter set to `true`! |
| timeToWaitForATTUserAuthorization | double | Delays the SDK start for x seconds until the user either accepts the consent dialog, declines it, or the timer runs out. |
| appInviteOneLink | String | The [OneLink template ID](https://support.appsflyer.com/hc/en-us/articles/115004480866-User-invite-attribution#parameters) that is used to generate a User Invite, this is not a required field in the `AppsFlyerOptions`, you may choose to set it later via the appropriate API. |
| showDebug | bool | Debug mode - set to `true` for testing only, do not release to production with this parameter set to `true`! |
| timeToWaitForATTUserAuthorization | double | Delays the SDK start for x seconds until the user either accepts the consent dialog, declines it, or the timer runs out. |
| appInviteOneLink | String | The [OneLink template ID](https://support.appsflyer.com/hc/en-us/articles/115004480866-User-invite-attribution#parameters) that is used to generate a User Invite, this is not a required field in the `AppsFlyerOptions`, you may choose to set it later via the appropriate API. |
| disableAdvertisingIdentifier| bool | Opt-out of the collection of Advertising Identifiers, which include OAID, AAID, GAID and IDFA. |
| disableCollectASA | bool | Opt-out of the Apple Search Ads attributions. |
| manualStart | bool | Prevents from the SDK from sending the launch request after using appsFlyer.initSdk(...). When using this property, the apps needs to manually trigger the appsFlyer.startSdk() API to report the app launch.|




Expand Down Expand Up @@ -128,6 +133,12 @@ _appsflyerSdk.initSdk(
registerOnDeepLinkingCallback: true)
```

---
##### <a id="startSDK"> **`startSDK()` (Added in 6.13.0)**
In version 6.13.0 of the appslfyer-flutter-plugin SDK we added the option of splitting between the initialization stage and start stage. All you need to do is add the property manualStart: true to the init object, and later call appsFlyer.startSdk() whenever you decide. If this property is set to false or doesn’t exist, the sdk will start after calling appsFlyer.initSdk(...).
```dart
_appsflyerSdk.startSDK();
```
---
#### <a id="onAppOpenAttribution"> **`onAppOpenAttribution(Func)`
- Trigger callback when onAppOpenAttribution is activated on the native side
Expand Down Expand Up @@ -258,6 +269,78 @@ _Example:_
```dart
appsFlyerSdk.enableLocationCollection(true);
```
---
**<a id="enableTCFDataCollection"> `enableTCFDataCollection(bool shouldCollect)`**

The `enableTCFDataCollection` method is employed to control the automatic collection of the Transparency and Consent Framework (TCF) data. By setting this flag to `true`, the system is instructed to automatically collect TCF data. Conversely, setting it to `false` prevents such data collection.

_Example:_
```dart
appsFlyerSdk.enableTCFDataCollection(true);
```
---
**<a id="setConsentData"> `setConsentData(Map<String, Object> consentData)`**

The `AppsflyerConsent` object helps manage user consent settings. By using the setConsentData we able to manually collect the TCF data. You can create an instance for users subject to GDPR or otherwise:

1. Users subjected to GDPR:

```dart
var forGdpr = _appsflyerSdk.forGDPRUser(
hasConsentForDataUsage: true,
hasConsentForAdsPersonalization: true
);
_appsflyerSdk.setConsentData(forGdpr);
```

2. Users not subject to GDPR:

```dart
var nonGdpr = _appsflyerSdk.nonGDPRUser();
_appsflyerSdk.setConsentData(nonGdpr);
```

The `_appsflyerSdk` handles consent data with `setConsentData` method, where you can pass the desired `AppsflyerConsent` instance.

---
To reflect TCF data in the conversion (first launch) payload, it's crucial to configure `enableTCFDataCollection` **or** `setConsentData` between the SDK initialization and start phase. Follow the example provided:

```dart
// Set AppsFlyerOption - make sure to set manualStart to true
final AppsFlyerOptions options = AppsFlyerOptions(
afDevKey: dotenv.env["DEV_KEY"]!,
appId: dotenv.env["APP_ID"]!,
showDebug: true,
timeToWaitForATTUserAuthorization: 15,
manualStart: true);
_appsflyerSdk = AppsflyerSdk(options);
// Init the AppsFlyer SDK
_appsflyerSdk.initSdk(
registerConversionDataCallback: true,
registerOnAppOpenAttributionCallback: true,
registerOnDeepLinkingCallback: true);
// Set configurations to the SDK
// Enable TCF Data Collection
_appsflyerSdk.enableTCFDataCollection(true);
// Set Consent Data
// If user is subject to GDPR
// var forGdpr = _appsflyerSdk.forGDPRUser(hasConsentForDataUsage: true, hasConsentForAdsPersonalization: true);
// _appsflyerSdk.setConsentData(forGdpr);
// If user is not subject to GDPR
var nonGdpr = _appsflyerSdk.nonGDPRUser();
_appsflyerSdk.setConsentData(nonGdpr);
// Here we start a session
_appsflyerSdk.startSDK();
```

Following this sequence ensures that the consent configurations take effect before the AppsFlyer SDK starts, providing accurate consent data in the first launch payload.
Note: You need to use either `enableTCFDataCollection` or `setConsentData` if you use both of them our backend will prioritize the provided consent data from `setConsentData`.

---
**<a id="setCustomerUserId"> `void setCustomerUserId(String userId)`**

Expand Down
Loading

0 comments on commit 080ebbe

Please sign in to comment.