diff --git a/CHANGELOG.md b/CHANGELOG.md
index 67e2559..cb93dfd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,9 @@
# Versions
+## 6.15.1
+- Implementation of the new logAdRevenue API for iOS and Android
+- Documentation update for the new logAdRevenue API
+- Update iOS version to 6.15.1
+- Update Android version to 6.15.1
## 6.14.3
- Fixed mapOptions issue with manualStart
- Inherit Privacy Manifest from the native iOS SDK via Cocoapods
diff --git a/README.md b/README.md
index 130c50f..5a68ad6 100644
--- a/README.md
+++ b/README.md
@@ -12,8 +12,8 @@
### This plugin is built for
-- Android AppsFlyer SDK **v6.14.0**
-- iOS AppsFlyer SDK **v6.14.3**
+- Android AppsFlyer SDK **v6.15.1**
+- iOS AppsFlyer SDK **v6.15.1**
## ❗❗ Breaking changes when updating to v6.x.x❗❗
diff --git a/android/build.gradle b/android/build.gradle
index dfae0b9..9669568 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -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.14.0'
+ implementation 'com.appsflyer:af-android-sdk:6.15.1'
implementation 'com.android.installreferrer:installreferrer:2.1'
}
\ No newline at end of file
diff --git a/android/src/main/java/com/appsflyer/appsflyersdk/AppsFlyerConstants.java b/android/src/main/java/com/appsflyer/appsflyersdk/AppsFlyerConstants.java
index 36a8c25..b6f419c 100644
--- a/android/src/main/java/com/appsflyer/appsflyersdk/AppsFlyerConstants.java
+++ b/android/src/main/java/com/appsflyer/appsflyersdk/AppsFlyerConstants.java
@@ -1,7 +1,7 @@
package com.appsflyer.appsflyersdk;
public class AppsFlyerConstants {
- final static String PLUGIN_VERSION = "6.14.3";
+ final static String PLUGIN_VERSION = "6.15.1";
final static String AF_APP_INVITE_ONE_LINK = "appInviteOneLink";
final static String AF_HOST_PREFIX = "hostPrefix";
final static String AF_HOST_NAME = "hostName";
diff --git a/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java b/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java
index 4c45025..bc66b4a 100644
--- a/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java
+++ b/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java
@@ -9,12 +9,14 @@
import android.os.Looper;
import android.util.Log;
+import com.appsflyer.AFAdRevenueData;
import com.appsflyer.AFLogger;
import com.appsflyer.AppsFlyerConsent;
import com.appsflyer.AppsFlyerConversionListener;
import com.appsflyer.AppsFlyerInAppPurchaseValidatorListener;
import com.appsflyer.AppsFlyerLib;
import com.appsflyer.AppsFlyerProperties;
+import com.appsflyer.MediationNetwork;
import com.appsflyer.deeplink.DeepLinkListener;
import com.appsflyer.deeplink.DeepLinkResult;
import com.appsflyer.share.CrossPromotionHelper;
@@ -344,6 +346,9 @@ public void onMethodCall(MethodCall call, Result result) {
case "addPushNotificationDeepLinkPath":
addPushNotificationDeepLinkPath(call, result);
break;
+ case "logAdRevenue":
+ logAdRevenue(call, result);
+ break;
default:
result.notImplemented();
break;
@@ -954,6 +959,57 @@ private void logEvent(MethodCall call, MethodChannel.Result result) {
result.success(true);
}
+ private void logAdRevenue(MethodCall call, Result result) {
+ try {
+ String monetizationNetwork = requireNonNullArgument(call, "monetizationNetwork");
+ String currencyIso4217Code = requireNonNullArgument(call, "currencyIso4217Code");
+ double revenue = requireNonNullArgument(call,"revenue");
+ String mediationNetworkString = requireNonNullArgument(call,"mediationNetwork");
+
+ MediationNetwork mediationNetwork = MediationNetwork.valueOf(mediationNetworkString.toUpperCase());
+
+ // No null check for additionalParameters since it's acceptable for it to be null (optional data)
+ Map additionalParameters = call.argument("additionalParameters");
+
+ AFAdRevenueData adRevenueData = new AFAdRevenueData(
+ monetizationNetwork,
+ mediationNetwork,
+ currencyIso4217Code,
+ revenue
+ );
+
+ AppsFlyerLib.getInstance().logAdRevenue(adRevenueData, additionalParameters);
+ result.success(true);
+
+ } catch (IllegalArgumentException e) {
+ // The IllegalArgumentException could come from either requireNonNullArgument or valueOf methods.
+ result.error("INVALID_ARGUMENT_PROVIDED", e.getMessage(), null);
+ }
+ catch (Throwable t) {
+ result.error("UNEXPECTED_ERROR", "[logAdRevenue]: An unexpected error occurred: " + t.getMessage(), null);
+ Log.e("AppsFlyer", "Unexpected exception occurred: [logAdRevenue]", t);
+ }
+ }
+
+ /**
+ * Utility method to ensure that an argument with the specified name is not null.
+ * If the argument is null, this method will throw an IllegalArgumentException.
+ * The calling method can then terminate immediately without further processing.
+ *
+ * @param call The MethodCall from Flutter, containing all the arguments.
+ * @param argumentName The name of the argument expected in the MethodCall.
+ * @param The type of the argument being checked for nullity.
+ * @return The argument value if it is not null; throw IllegalArgumentException otherwise.
+ */
+ private T requireNonNullArgument(MethodCall call, String argumentName) throws IllegalArgumentException {
+ T argument = call.argument(argumentName);
+ if (argument == null) {
+ Log.e("AppsFlyer", "Exception occurred when trying to: " + call.method + "->" + argumentName + " must not be null");
+ throw new IllegalArgumentException("[" + call.method + "]: " + argumentName + " must not be null");
+ }
+ return argument;
+ }
+
//RD-65582
private void sendCachedCallbacksToDart() {
if (cachedDeepLinkResult != null) {
diff --git a/doc/API.md b/doc/API.md
index 390ae9e..94cc932 100644
--- a/doc/API.md
+++ b/doc/API.md
@@ -4,6 +4,8 @@
## Types
- [AppsFlyerOptions](#appsflyer-options)
+- [AdRevenueData](#AdRevenueData)
+- [AFMediationNetwork](#AFMediationNetwork)
## Methods
- [initSdk](#initSdk)
@@ -52,11 +54,12 @@
- [getOutOfStore](#getOutOfStore)
- [setDisableNetworkData](#setDisableNetworkData)
- [performOnDeepLinking](#performondeeplinking)
+- [logAdRevenue](#logAdRevenue) - Since 6.15.1
---
-##### **`AppsflyerSdk(Map options)`**
+##### **`AppsflyerSdk(Map options)`**
| parameter | type | description |
| --------- | ----- | ----------------- |
@@ -116,6 +119,42 @@ Once `AppsflyerSdk` object is created, you can call `initSdk` method.
---
+##### **`AdRevenueData`**
+
+| parameter | type | description |
+| --------- | ------------------ | ----------------- |
+| `monetizationNetwork` | `String` | |
+| `mediationNetwork` | `String` | value must be taken from `AFMediationNetwork` |
+| `currencyIso4217Code` | `String` | |
+| `revenue` | `double` | |
+| `additionalParameters` | `Map?` | |
+
+---
+
+##### **`AFMediationNetwork`**
+an enumeration that includes the supported mediation networks by AppsFlyer.
+
+
+| networks |
+| -------- |
+| ironSource
+applovinMax
+googleAdMob
+fyber
+appodeal
+admost
+topon
+tradplus
+yandex
+chartboost
+unity
+toponPte
+customMediation
+directMonetizationNetwork |
+
+---
+
+
##### **`initSdk({bool registerConversionDataCallback, bool registerOnAppOpenAttributionCallback}) async` (Changed in 1.2.2)**
initialize the SDK, using the options initialized from the constructor|
@@ -561,7 +600,7 @@ This call matches the following payload structure:
1. First define the Onelink ID (find it in the AppsFlyer dashboard in the onelink section:
- **`Future setAppInviteOneLinkID(String oneLinkID, Function callback)`**
+**`Future setAppInviteOneLinkID(String oneLinkID, Function callback)`**
2. Set the AppsFlyerInviteLinkParams class to set the query params in the user invite link:
@@ -579,7 +618,7 @@ class AppsFlyerInviteLinkParams {
3. Call the generateInviteLink API to generate the user invite link. Use the success and error callbacks for handling.
- **`void generateInviteLink(AppsFlyerInviteLinkParams parameters, Function success, Function error)`**
+**`void generateInviteLink(AppsFlyerInviteLinkParams parameters, Function success, Function error)`**
_Example:_
@@ -653,7 +692,7 @@ appsFlyerSdk.setCurrentDeviceLanguage("en");
---
** `void setSharingFilterForPartners(List partners)`**
-`setSharingFilter` & `setSharingFilterForAllPartners` APIs were deprecated!
+`setSharingFilter` & `setSharingFilterForAllPartners` APIs were deprecated!
Use `setSharingFilterForPartners` instead.
@@ -672,9 +711,9 @@ appsFlyerSdk.setSharingFilterForPartners(['googleadwords_int', 'all']);
---
** `void setOneLinkCustomDomain(List brandDomains)`**
-Use this API in order to set branded domains.
+Use this API in order to set branded domains.
-Find more information in the [following article on branded domains](https://support.appsflyer.com/hc/en-us/articles/360002329137-Implementing-Branded-Links).
+Find more information in the [following article on branded domains](https://support.appsflyer.com/hc/en-us/articles/360002329137-Implementing-Branded-Links).
_Example:_
```dart
@@ -823,3 +862,53 @@ Note:
This API will trigger the `appsflyerSdk.onDeepLink` callback. In the fo
_appsflyerSdk.startSDK();
}
```
+
+---
+
+### ** `void logAdRevenue(AdRevenueData adRevenueData)`**
+
+The logAdRevenue API is designed to simplify the process of logging ad revenue events to AppsFlyer from your Flutter application. This API tracks revenue generated from advertisements, enriching your monetization analytics. Below you will find instructions on how to use this API correctly, along with detailed descriptions and examples for various input scenarios.
+
+### **Usage:**
+To use the logAdRevenue method, you must:
+
+1. Prepare an instance of `AdRevenueData` with the required information about the ad revenue event.
+1. Call `logAdRevenue` with the `AdRevenueData` instance.
+
+**AdRevenueData Class**
+[AdRevenueData](#AdRevenueData) is a data class representing all the relevant information about an ad revenue event:
+
+* `monetizationNetwork`: The source network from which the revenue was generated (e.g., AdMob, Unity Ads).
+* `mediationNetwork`: The mediation platform managing the ad (use AFMediationNetwork enum for supported networks).
+* `currencyIso4217Code`: The ISO 4217 currency code representing the currency of the revenue amount (e.g., "USD", "EUR").
+* `revenue`: The amount of revenue generated from the ad.
+* `additionalParameters`: Additional parameters related to the ad revenue event (optional).
+
+
+**AFMediationNetwork Enum**
+[AFMediationNetwork](#AFMediationNetwork) is an enumeration that includes the supported mediation networks by AppsFlyer. It's important to use this enum to ensure you provide a valid network identifier to the logAdRevenue API.
+
+### Example:
+```dart
+// Instantiate AdRevenueData with the ad revenue details.
+AdRevenueData adRevenueData = AdRevenueData(
+ monetizationNetwork: "GoogleAdMob", // Replace with your actual monetization network.
+ mediationNetwork: AFMediationNetwork.applovinMax.value, // Use the value from the enum.
+ currencyIso4217Code: "USD",
+ revenue: 1.23,
+ additionalParameters: {
+ // Optional additional parameters can be added here. This is an example, can be discard if not needed.
+ 'adUnitId': 'ca-app-pub-XXXX/YYYY',
+ 'ad_network_click_id': '12345'
+ }
+);
+
+// Log the ad revenue event.
+logAdRevenue(adRevenueData);
+```
+
+**Additional Points**
+* Mediation network input must be from the provided [AFMediationNetwork](#AFMediationNetwork)
+ enum to ensure proper processing by AppsFlyer. For instance, use `AFMediationNetwork.googleAdMob.value` to denote Google AdMob as the Mediation Network.
+* The `additionalParameters` map is optional. Use it to pass any extra information you have regarding the ad revenue event; this information could be useful for more refined analytics.
+* Make sure the `currencyIso4217Code` adheres to the appropriate standard. Misconfigured currency code may result in incorrect revenue tracking.
\ No newline at end of file
diff --git a/ios/Classes/AppsflyerSdkPlugin.h b/ios/Classes/AppsflyerSdkPlugin.h
index a6055a9..0ae703a 100644
--- a/ios/Classes/AppsflyerSdkPlugin.h
+++ b/ios/Classes/AppsflyerSdkPlugin.h
@@ -18,7 +18,7 @@
@end
// Appsflyer JS objects
-#define kAppsFlyerPluginVersion @"6.14.3"
+#define kAppsFlyerPluginVersion @"6.15.1"
#define afDevKey @"afDevKey"
#define afAppId @"afAppId"
#define afIsDebug @"isDebug"
diff --git a/ios/Classes/AppsflyerSdkPlugin.m b/ios/Classes/AppsflyerSdkPlugin.m
index 9d0fec4..4295044 100644
--- a/ios/Classes/AppsflyerSdkPlugin.m
+++ b/ios/Classes/AppsflyerSdkPlugin.m
@@ -94,7 +94,7 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
}else if([@"setIsUpdate" isEqualToString:call.method]){
//
}else if([@"setCustomerUserId" isEqualToString:call.method]){
- [self setCustomerUserId:call result:result];
+ [self setCustomerUserId:call result:result];
}else if([@"setCustomerIdAndLogSession" isEqualToString:call.method]){
[self setCustomerUserId:call result:result];
}else if([@"setCurrencyCode" isEqualToString:call.method ]){
@@ -130,7 +130,7 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
}else if([@"setOneLinkCustomDomain" isEqualToString:call.method]){
[self setOneLinkCustomDomain:call result:result];
}else if([@"setPushNotification" isEqualToString:call.method]){
- [self setPushNotification:call result:result];
+ [self setPushNotification:call result:result];
}else if([@"sendPushNotificationData" isEqualToString:call.method]){
[self sendPushNotificationData:call result:result];
}else if([@"useReceiptValidationSandbox" isEqualToString:call.method]){
@@ -157,6 +157,8 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
[self enableTCFDataCollection:call result:result];
}else if([@"setConsentData" isEqualToString:call.method]){
[self setConsentData:call result:result];
+ }else if([@"logAdRevenue" isEqualToString:call.method]){
+ [self logAdRevenue:call result:result];
}
else{
result(FlutterMethodNotImplemented);
@@ -189,23 +191,106 @@ - (void)startSDK:(FlutterMethodCall*)call result:(FlutterResult)result {
- (void)setConsentData:(FlutterMethodCall*)call result:(FlutterResult)result {
NSDictionary* consentDict = call.arguments[@"consentData"];
-
+
BOOL isUserSubjectToGDPR = [consentDict[@"isUserSubjectToGDPR"] boolValue];
BOOL hasConsentForDataUsage = [consentDict[@"hasConsentForDataUsage"] boolValue];
BOOL hasConsentForAdsPersonalization = [consentDict[@"hasConsentForAdsPersonalization"] boolValue];
-
+
AppsFlyerConsent *consentData;
if(isUserSubjectToGDPR){
consentData = [[AppsFlyerConsent alloc] initForGDPRUserWithHasConsentForDataUsage:hasConsentForDataUsage
- hasConsentForAdsPersonalization:hasConsentForAdsPersonalization];
+ hasConsentForAdsPersonalization:hasConsentForAdsPersonalization];
}else{
consentData = [[AppsFlyerConsent alloc] initNonGDPRUser];
}
-
+
[[AppsFlyerLib shared] setConsentData:consentData];
result(nil);
}
+- (void)logAdRevenue:(FlutterMethodCall*)call result:(FlutterResult)result {
+ @try {
+ NSString *monetizationNetwork = [self requireNonNullArgumentWithCall:call result:result argumentName:@"monetizationNetwork" errorCode:@"NULL_MONETIZATION_NETWORK"];
+ if (monetizationNetwork == nil) return;
+
+ NSString *currencyIso4217Code = [self requireNonNullArgumentWithCall:call result:result argumentName:@"currencyIso4217Code" errorCode:@"NULL_CURRENCY_CODE"];
+ if (currencyIso4217Code == nil) return;
+
+ NSNumber *revenueValue = [self requireNonNullArgumentWithCall:call result:result argumentName:@"revenue" errorCode:@"NULL_REVENUE"];
+ if (revenueValue == nil) return;
+
+ NSString *mediationNetworkString = [self requireNonNullArgumentWithCall:call result:result argumentName:@"mediationNetwork" errorCode:@"NULL_MEDIATION_NETWORK"];
+ if (mediationNetworkString == nil) return;
+
+ // Fetching the actual mediationNetwork Enum
+ AppsFlyerAdRevenueMediationNetworkType mediationNetwork = [self getEnumValueFromString:mediationNetworkString];
+ if (mediationNetwork == -1) { //mediation network not found.
+ result([FlutterError errorWithCode:@"INVALID_MEDIATION_NETWORK"
+ message:@"The provided mediation network is not supported."
+ details:nil]);
+ return;
+ }
+
+ NSDictionary *additionalParameters = call.arguments[@"additionalParameters"];
+ if ([additionalParameters isEqual:[NSNull null]]) {
+ additionalParameters = nil; // Set to nil to avoid sending NSNull to the SDK which cannot be proseesed.
+ }
+
+ AFAdRevenueData *adRevenueData = [[AFAdRevenueData alloc]
+ initWithMonetizationNetwork:monetizationNetwork
+ mediationNetwork:mediationNetwork
+ currencyIso4217Code:currencyIso4217Code
+ eventRevenue:revenueValue];
+
+ [[AppsFlyerLib shared] logAdRevenue:adRevenueData additionalParameters:additionalParameters];
+
+ } @catch (NSException *exception) {
+ result([FlutterError errorWithCode:@"UNEXPECTED_ERROR"
+ message:[NSString stringWithFormat:@"[logAdRevenue]: An error occurred retrieving method arguments: %@", exception.reason]
+ details:nil]);
+ NSLog(@"AppsFlyer, Exception occurred in [logAdRevenue]: %@", exception.reason);
+ }
+
+}
+
+- (AppsFlyerAdRevenueMediationNetworkType)getEnumValueFromString:(NSString *)mediationNetworkString {
+ NSDictionary *stringToEnumMap = @{
+ @"googleadmob": @(AppsFlyerAdRevenueMediationNetworkTypeGoogleAdMob),
+ @"ironsource": @(AppsFlyerAdRevenueMediationNetworkTypeIronSource),
+ @"applovinmax": @(AppsFlyerAdRevenueMediationNetworkTypeApplovinMax),
+ @"fyber": @(AppsFlyerAdRevenueMediationNetworkTypeFyber),
+ @"appodeal": @(AppsFlyerAdRevenueMediationNetworkTypeAppodeal),
+ @"Admost": @(AppsFlyerAdRevenueMediationNetworkTypeAdmost),
+ @"Topon": @(AppsFlyerAdRevenueMediationNetworkTypeTopon),
+ @"Tradplus": @(AppsFlyerAdRevenueMediationNetworkTypeTradplus),
+ @"Yandex": @(AppsFlyerAdRevenueMediationNetworkTypeYandex),
+ @"chartboost": @(AppsFlyerAdRevenueMediationNetworkTypeChartBoost),
+ @"Unity": @(AppsFlyerAdRevenueMediationNetworkTypeUnity),
+ @"toponpte": @(AppsFlyerAdRevenueMediationNetworkTypeToponPte),
+ @"customMediation": @(AppsFlyerAdRevenueMediationNetworkTypeCustom),
+ @"directMonetizationNetwork": @(AppsFlyerAdRevenueMediationNetworkTypeDirectMonetization)
+ };
+
+ NSNumber *enumValueNumber = stringToEnumMap[mediationNetworkString];
+ if (enumValueNumber) {
+ return (AppsFlyerAdRevenueMediationNetworkType)[enumValueNumber integerValue];
+ } else {
+ return -1;
+ }
+}
+
+- (id)requireNonNullArgumentWithCall:(FlutterMethodCall*)call result:(FlutterResult)result argumentName:(NSString *)argumentName errorCode:(NSString *)errorCode {
+ id value = call.arguments[argumentName];
+ if (value == nil) {
+ result([FlutterError
+ errorWithCode:errorCode
+ message:[NSString stringWithFormat:@"%@ must not be null", argumentName]
+ details:nil]);
+ NSLog(@"AppsFlyer, %@ must not be null", argumentName);
+ }
+ return value;
+}
+
- (void)enableTCFDataCollection:(FlutterMethodCall*)call result:(FlutterResult)result {
BOOL shouldCollect = [call.arguments[@"shouldCollect"] boolValue];
[[AppsFlyerLib shared] enableTCFDataCollection:shouldCollect];
@@ -658,7 +743,7 @@ - (void)initSdkWithCall:(FlutterMethodCall*)call result:(FlutterResult)result{
}
[[AppsFlyerLib shared] setPluginInfoWith:AFSDKPluginFlutter pluginVersion:kAppsFlyerPluginVersion additionalParams:nil];
-
+
[AppsFlyerLib shared].appleAppID = appId;
[AppsFlyerLib shared].appsFlyerDevKey = devKey;
[AppsFlyerLib shared].isDebug = isDebug;
@@ -674,12 +759,12 @@ - (void)initSdkWithCall:(FlutterMethodCall*)call result:(FlutterResult)result{
if (timeToWaitForATTUserAuthorization != 0) {
[[AppsFlyerLib shared] waitForATTUserAuthorizationWithTimeoutInterval:timeToWaitForATTUserAuthorization];
}
-
+
if (manualStart == NO){
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
[[AppsFlyerLib shared] start];
}
-
+
//post notification for the deep link object that the bridge is set and he can handle deep link
[AppsFlyerAttribution shared].isBridgeReady = YES;
[[NSNotificationCenter defaultCenter] postNotificationName:AF_BRIDGE_SET object:self];
@@ -691,7 +776,7 @@ - (void)initSdkWithCall:(FlutterMethodCall*)call result:(FlutterResult)result{
-(void)logEventWithCall:(FlutterMethodCall*)call result:(FlutterResult)result{
NSString *eventName = call.arguments[afEventName];
NSDictionary *eventValues = call.arguments[afEventValues];
-
+
// Explicitily setting the values to be nil if call.arguments[afEventValues] returns .
if (eventValues == [NSNull null]) {
eventValues = nil;
diff --git a/ios/appsflyer_sdk.podspec b/ios/appsflyer_sdk.podspec
index 2c063dd..56145b3 100644
--- a/ios/appsflyer_sdk.podspec
+++ b/ios/appsflyer_sdk.podspec
@@ -3,7 +3,7 @@
#
Pod::Spec.new do |s|
s.name = 'appsflyer_sdk'
- s.version = '6.14.3'
+ s.version = '6.15.1'
s.summary = 'AppsFlyer Integration for Flutter'
s.description = <<-DESC
AppsFlyer is the market leader in mobile advertising attribution & analytics, helping marketers to pinpoint their targeting, optimize their ad spend and boost their ROI.
@@ -21,5 +21,5 @@ AppsFlyer is the market leader in mobile advertising attribution & analytics, he
s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.dependency 'Flutter'
- s.ios.dependency 'AppsFlyerFramework','6.14.3'
+ s.ios.dependency 'AppsFlyerFramework','6.15.1'
end
diff --git a/lib/appsflyer_sdk.dart b/lib/appsflyer_sdk.dart
index 8086305..1d8ab74 100644
--- a/lib/appsflyer_sdk.dart
+++ b/lib/appsflyer_sdk.dart
@@ -18,3 +18,4 @@ part 'src/udl/deep_link_result.dart';
part 'src/udl/deeplink.dart';
part 'src/appsflyer_consent.dart';
part 'src/appsflyer_request_listener.dart';
+part 'src/appsflyer_ad_revenue_data.dart';
diff --git a/lib/src/appsflyer_ad_revenue_data.dart b/lib/src/appsflyer_ad_revenue_data.dart
new file mode 100644
index 0000000..7482cf7
--- /dev/null
+++ b/lib/src/appsflyer_ad_revenue_data.dart
@@ -0,0 +1,27 @@
+part of appsflyer_sdk;
+
+class AdRevenueData {
+ final String monetizationNetwork;
+ final String mediationNetwork;
+ final String currencyIso4217Code;
+ final double revenue;
+ final Map? additionalParameters;
+
+ AdRevenueData({
+ required this.monetizationNetwork,
+ required this.mediationNetwork,
+ required this.currencyIso4217Code,
+ required this.revenue,
+ this.additionalParameters
+ });
+
+ Map toMap() {
+ return {
+ 'monetizationNetwork': monetizationNetwork,
+ 'mediationNetwork': mediationNetwork,
+ 'currencyIso4217Code': currencyIso4217Code,
+ 'revenue': revenue,
+ 'additionalParameters': additionalParameters
+ };
+ }
+}
diff --git a/lib/src/appsflyer_constants.dart b/lib/src/appsflyer_constants.dart
index 0ee155e..6f86f56 100644
--- a/lib/src/appsflyer_constants.dart
+++ b/lib/src/appsflyer_constants.dart
@@ -1,9 +1,6 @@
part of appsflyer_sdk;
-enum EmailCryptType {
- EmailCryptTypeNone,
- EmailCryptTypeSHA256
-}
+enum EmailCryptType { EmailCryptTypeNone, EmailCryptTypeSHA256 }
class AppsflyerConstants {
static const String AF_DEV_KEY = "afDevKey";
@@ -30,3 +27,53 @@ class AppsflyerConstants {
static const String DISABLE_ADVERTISING_IDENTIFIER =
"disableAdvertisingIdentifier";
}
+
+enum AFMediationNetwork {
+ ironSource,
+ applovinMax,
+ googleAdMob,
+ fyber,
+ appodeal,
+ admost,
+ topon,
+ tradplus,
+ yandex,
+ chartboost,
+ unity,
+ toponPte,
+ customMediation,
+ directMonetizationNetwork;
+
+ String get value {
+ switch (this) {
+ case AFMediationNetwork.ironSource:
+ return "ironsource";
+ case AFMediationNetwork.applovinMax:
+ return "applovinmax";
+ case AFMediationNetwork.googleAdMob:
+ return "googleadmob";
+ case AFMediationNetwork.fyber:
+ return "fyber";
+ case AFMediationNetwork.appodeal:
+ return "appodeal";
+ case AFMediationNetwork.admost:
+ return "Admost";
+ case AFMediationNetwork.topon:
+ return "Topon";
+ case AFMediationNetwork.tradplus:
+ return "Tradplus";
+ case AFMediationNetwork.yandex:
+ return "Yandex";
+ case AFMediationNetwork.chartboost:
+ return "chartboost";
+ case AFMediationNetwork.unity:
+ return "Unity";
+ case AFMediationNetwork.toponPte:
+ return "toponpte";
+ case AFMediationNetwork.customMediation:
+ return "customMediation";
+ case AFMediationNetwork.directMonetizationNetwork:
+ return "directMonetizationNetwork";
+ }
+ }
+}
diff --git a/lib/src/appsflyer_sdk.dart b/lib/src/appsflyer_sdk.dart
index 6952286..c4cde1b 100644
--- a/lib/src/appsflyer_sdk.dart
+++ b/lib/src/appsflyer_sdk.dart
@@ -237,6 +237,12 @@ class AppsflyerSdk {
"logEvent", {'eventName': eventName, 'eventValues': eventValues});
}
+
+ /// Log ad revenue API.
+ void logAdRevenue(AdRevenueData adRevenueData) {
+ _methodChannel.invokeMethod("logAdRevenue", adRevenueData.toMap());
+ }
+
/// Sets the host name and the host prefix.
/// This is only relevant if you need to switch between HTTPS environments.
void setHost(String hostPrefix, String hostName) {
diff --git a/pubspec.yaml b/pubspec.yaml
index fb17829..90a5a68 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,11 +1,11 @@
name: appsflyer_sdk
description: A Flutter plugin for AppsFlyer SDK. Supports iOS and Android.
-version: 6.14.3
+version: 6.15.1
homepage: https://github.com/AppsFlyerSDK/flutter_appsflyer_sdk
environment:
- sdk: '>=2.12.0 <4.0.0'
+ sdk: '>=2.17.0 <4.0.0'
flutter: ">=1.10.0"
dependencies: