diff --git a/README.md b/README.md index a0130301..6edc0d53 100755 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ For lower versions of cordova-android please use plugin version 4.3.3 available - From version **6.1.10** the plugin uses cocoapods(NOT StaticLib) in order to support iOS app-kids Strict mode.
You can read more [here](https://support.appsflyer.com/hc/en-us/articles/207032066#integration-strict-mode-sdk) - From version **6.10.2** the plugin requires using the implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.6.20' in Android. +- From version **6.14.3** the plugin requires Target version 12 and higher in iOS. +- From version **6.15.1** the plugin requires adding the value '/usr/lib/swift' to Build Settings 'RunPath Search Paths' key in iOS. ---------- @@ -42,8 +44,13 @@ You can read more [here](https://support.appsflyer.com/hc/en-us/articles/2070320 ### This plugin is built for -- iOS AppsFlyerSDK **v6.14.3** -- Android AppsFlyerSDK **v6.14.0** +- iOS AppsFlyerSDK **v6.15.1** +- Android AppsFlyerSDK **v6.15.0** + +### ❗v6.15.1 Breaking Changes + +iOS platform: +The plugin requires adding the value '/usr/lib/swift' to Build Settings 'RunPath Search Paths' key in iOS, Otherwise there might be some compilation errors. ### ❗v6.14.3 Breaking Changes diff --git a/RELEASENOTES.md b/RELEASENOTES.md index acced19a..bf7b6ee9 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -1,3 +1,13 @@ +## 6.15.1 + Release date: *2024-09-02* + +- Cordova >> Update Plugin to v6.15.1 + +## 6.15.1 + Release date: *2024-09-02* + +- Cordova >> Update Plugin to v6.15.1 + ## 6.14.3 Release date: *2024-04-30* diff --git a/docs/API.md b/docs/API.md index 889d3323..d5afc07d 100755 --- a/docs/API.md +++ b/docs/API.md @@ -52,7 +52,8 @@ The list of available methods for this plugin is described below. | [`sendPushNotificationData`](#sendPushNotificationData) | `(Object data)` | Measure and get data from push-notification campaigns. | | [`setDisableNetworkData`](#setDisableNetworkData) | `(boolean disable)` | Use to opt-out of collecting the network operator name (carrier) and sim operator name from the device. | | [`setConsentData`](#setConsentData) | `(boolean disable)` | Use to manually collecting the consent data from the user. | -| [`enableTCFDataCollection`](#enableTCFDataCollection) | `(boolean enable)` | instruct the SDK to collect the TCF data from the device. | +| [`enableTCFDataCollection`](#enableTCFDataCollection) | `(boolean enable)` | instruct the SDK to collect the TCF data from the device. | +| [`logAdRevenue`](#logAdRevenue) | `(Object adRevenueData, Object additionalParams)` | Log ad revenue event. | --- @@ -799,6 +800,47 @@ window.plugins.appsFlyer.enableTCFDataCollection(true); ``` --- + +##### **`logAdRevenue(adRevenueData, additionalParams): void`** +log ad-revenue event. + +| parameter | type | description | +|------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `adRevenueData` | `Object` | the object must contain the following fields:
monetizationNetwork: String testMonetizationNetwork
mediationNetwork: MediationNetwork testMediationNetwork
currencyIso4217Code: String currencyByIso4217CodeFormat
revenue:double revenue | +| `additionalData` | `Object` | additional Params Data map, @Nullable | + + +*Example:* + +```javascript + +let mediationNetwork = MediationNetwork.TOPON; +let adRevenueData = { + 'monetizationNetwork': 'testMonetizationNetwork', + 'mediationNetwork': mediationNetwork, + 'currencyIso4217Code': 'USD', + 'revenue': 15.0 +}; +let additionalParams = { + 'additionalKey1':'additionalValue1', + 'additionalKey2':'additionalValue2' +} +window.plugins.appsFlyer.logAdRevenue(adRevenueData, additionalParams); + + +``` +Here's how you use `appsFlyer.logAdRevenue` within a Cordova app: + +1. Prepare the `adRevenueData` object as shown, including any additional parameters you wish to track along with the ad revenue event. +2. Call the `appsFlyer.logAdRevenue` method with the `adRevenueData` object. + +By passing all the required fields in `AFAdRevenueData`, you help ensure accurate tracking within the AppsFlyer platform. This enables you to analyze your ad revenue alongside other user acquisition data to optimize your app's overall monetization strategy. + +**Note:** +The `additionalParameters` object is optional. You can add any additional data you want to log with the ad revenue event in this object. This can be useful for detailed analytics or specific event tracking later on. Make sure that the custom parameters follow the data types and structures specified by AppsFlyer in their documentation. +--- + + ###
Deep linking Tracking diff --git a/package.json b/package.json index 2b7d693f..f2f417a6 100644 --- a/package.json +++ b/package.json @@ -1,52 +1,104 @@ { + "name": "cordova-plugin-appsflyer-sdk", - "version": "6.14.3", + + "version": "6.15.1", + "description": "Cordova AppsFlyer SDK Plugin", + "cordova": { + "id": "cordova-plugin-appsflyer-sdk", + "platforms": [ + "android", + "ios" + ] + }, + "repository": { + "type": "git", + "url": "git+https://github.com/AppsFlyerSDK/cordova-plugin-appsflyer-sdk.git" + }, + "keywords": [ + "cordova", + "appsflyer", + "ecosystem:cordova", + "cordova-android", + "cordova-ios" + ], + "engines": [ + { + "name": "cordova", + "version": ">=4.3.0" + } + ], + "author": "Appsflyer", + "license": { + "type": "MIT", + "url": "https://github.com/AppsFlyerSDK/appsflyer-cordova-plugin/blob/master/LICENSE" + }, + "bugs": { + "url": "https://github.com/AppsFlyerSDK/cordova-plugin-appsflyer-sdk/issues" + }, + "homepage": "https://github.com/AppsFlyerSDK/cordova-plugin-appsflyer-sdk#readme", + "scripts": { + "test": "npm run jshint", + "jshint": "node node_modules/jshint/bin/jshint www && node node_modules/jshint/bin/jshint src && node node_modules/jshint/bin/jshint tests", + "setupIonicCordova": "cd examples/ionic-cordova; npm install; ionic cordova plugin rm cordova-plugin-appsflyer-sdk --save; ionic cordova platform rm android; ionic cordova platform rm ios; ionic cordova plugin add cordova-plugin-appsflyer-sdk --save; ionic cordova platform add android; ionic cordova platform add ios", + "runIonicCordovaIos": "cd examples/ionic-cordova; ionic cordova prepare ios; ionic cordova run ios;", + "runIonicCordovaAndroid": "cd examples/ionic-cordova; ionic cordova prepare android; ionic cordova run android;", + "setupCordova": "cd examples/cordova; npm install; cordova plugin rm cordova-plugin-appsflyer-sdk --save; cordova platform rm android; cordova platform rm ios; cordova plugin add cordova-plugin-appsflyer-sdk --save; cordova platform add android; cordova platform add ios", + "runCordovaIos": "cd examples/cordova; cordova prepare ios; cordova run ios;", + "runCordovaAndroid": "cd examples/cordova; cordova prepare android; cordova run android;" + }, + "devDependencies": { + "jshint": "^2.6.0" + }, + "dependencies": {} + } + diff --git a/plugin.xml b/plugin.xml index 054aa3a6..d468a3d2 100644 --- a/plugin.xml +++ b/plugin.xml @@ -91,10 +91,9 @@ - + - diff --git a/src/android/com/appsflyer/cordova/plugin/AppsFlyerConstants.java b/src/android/com/appsflyer/cordova/plugin/AppsFlyerConstants.java index 0cd7b5e3..7acf7db9 100644 --- a/src/android/com/appsflyer/cordova/plugin/AppsFlyerConstants.java +++ b/src/android/com/appsflyer/cordova/plugin/AppsFlyerConstants.java @@ -6,7 +6,7 @@ public class AppsFlyerConstants { - final static String PLUGIN_VERSION = "6.14.0"; + final static String PLUGIN_VERSION = "6.15.1"; final static String NO_DEVKEY_FOUND = "AppsFlyer 'devKey' is missing or empty"; final static String NO_GCM_PROJECT_NUMBER_PROVIDED = "No GCM Project number provided"; final static String SUCCESS = "Success"; diff --git a/src/android/com/appsflyer/cordova/plugin/AppsFlyerPlugin.java b/src/android/com/appsflyer/cordova/plugin/AppsFlyerPlugin.java index e37358d0..5cc81b6f 100644 --- a/src/android/com/appsflyer/cordova/plugin/AppsFlyerPlugin.java +++ b/src/android/com/appsflyer/cordova/plugin/AppsFlyerPlugin.java @@ -62,6 +62,8 @@ import com.appsflyer.internal.platform_extension.Plugin; import com.appsflyer.internal.platform_extension.PluginInfo; import com.appsflyer.AppsFlyerConsent; +import com.appsflyer.MediationNetwork; +import com.appsflyer.AFAdRevenueData; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaInterface; @@ -176,10 +178,58 @@ public boolean execute(final String action, JSONArray args, CallbackContext call return setConsentData(args); } else if ("enableTCFDataCollection".equals(action)) { return enableTCFDataCollection(args); + } else if ("logAdRevenue".equals(action)) { + return logAdRevenue(args); } return false; } + /** + * log AdRevenue event + * + * @param args - event params + * @return true + */ + private boolean logAdRevenue(JSONArray args) { + cordova.getThreadPool().execute(() -> { + Map additionalParameters = null; + try { + if(!args.get(0).equals(null)){ + JSONObject afAdRevenueDataJsonObj = args.getJSONObject(0); + String monetizationNetwork = afAdRevenueDataJsonObj.optString("monetizationNetwork", null); + String mediationNetwork = afAdRevenueDataJsonObj.optString("mediationNetwork", null); + String currencyIso4217Code = afAdRevenueDataJsonObj.optString("currencyIso4217Code", null); + double revenue = afAdRevenueDataJsonObj.optDouble("revenue", -1); + MediationNetwork mediationNetworkEnumVal = null; + + if(mediationNetwork != null){ + for(MediationNetwork mediationNetworkEnum: MediationNetwork.values()){ + if(mediationNetworkEnum.getValue().equals(mediationNetwork)){ + mediationNetworkEnumVal = mediationNetworkEnum; + continue; + } + } + } + + if(!args.get(1).equals(null)){ + JSONObject additionalParametersJson = args.getJSONObject(1); + additionalParameters = toObjectMap(additionalParametersJson); + } + if(mediationNetworkEnumVal != null){ + AFAdRevenueData afAdRevenueData = new AFAdRevenueData(monetizationNetwork, mediationNetworkEnumVal, currencyIso4217Code, revenue); + AppsFlyerLib.getInstance().logAdRevenue(afAdRevenueData, additionalParameters); + } + else{ + Log.d("AppsFlyer", "Could not log Ad-Revenue event, bad inputs"); + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + }); + return true; + } + /** * set consent data according to GDPR if applies or not. * diff --git a/src/android/cordovaAF.gradle b/src/android/cordovaAF.gradle index 70d1d051..011933b3 100644 --- a/src/android/cordovaAF.gradle +++ b/src/android/cordovaAF.gradle @@ -4,7 +4,7 @@ repositories { dependencies { implementation 'com.android.installreferrer:installreferrer:2.1' - implementation 'com.appsflyer:af-android-sdk:6.14.0@aar' + implementation 'com.appsflyer:af-android-sdk:6.15.0@aar' implementation 'com.android.support:support-annotations:28.0.0' implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.6.20' } diff --git a/src/ios/AppsFlyerPlugin.h b/src/ios/AppsFlyerPlugin.h index 5eb390a2..dc708fe7 100755 --- a/src/ios/AppsFlyerPlugin.h +++ b/src/ios/AppsFlyerPlugin.h @@ -33,6 +33,7 @@ - (void)setCurrentDeviceLanguage:(CDVInvokedUrlCommand*)command; - (void)setAdditionalData:(CDVInvokedUrlCommand*)command; - (void)setConsentData:(CDVInvokedUrlCommand*)command; +- (void)logAdRevenue:(CDVInvokedUrlCommand*)command; - (void)enableTCFDataCollection:(CDVInvokedUrlCommand*)command; - (void)setSharingFilter:(CDVInvokedUrlCommand*)command __attribute__((deprecated)); - (void)setSharingFilterForAllPartners:(CDVInvokedUrlCommand*)command __attribute__((deprecated)); diff --git a/src/ios/AppsFlyerPlugin.m b/src/ios/AppsFlyerPlugin.m index f88ba119..796ccc79 100755 --- a/src/ios/AppsFlyerPlugin.m +++ b/src/ios/AppsFlyerPlugin.m @@ -96,7 +96,7 @@ - (void)initSdk:(CDVInvokedUrlCommand*)command } // Initialize the SDK - [[AppsFlyerLib shared] setPluginInfoWith:AFSDKPluginCordova pluginVersion:@"6.14.3" additionalParams:nil]; + [[AppsFlyerLib shared] setPluginInfoWith:AFSDKPluginCordova pluginVersion:@"6.15.1" additionalParams:nil]; [AppsFlyerLib shared].appleAppID = appId; [AppsFlyerLib shared].appsFlyerDevKey = devKey; [AppsFlyerLib shared].isDebug = isDebug; @@ -196,6 +196,100 @@ - (void)setCurrencyCode:(CDVInvokedUrlCommand*)command [AppsFlyerLib shared].currencyCode = currencyId; } + +- (AppsFlyerAdRevenueMediationNetworkType)getEnumValueFromString:(NSString *)mediationNetworkString { + NSDictionary *stringToEnumMap = @{ + @"googleadmob": @(AppsFlyerAdRevenueMediationNetworkTypeGoogleAdMob), + @"ironsource": @(AppsFlyerAdRevenueMediationNetworkTypeIronSource), + @"applovinmax": @(AppsFlyerAdRevenueMediationNetworkTypeApplovinMax), + @"fyber": @(AppsFlyerAdRevenueMediationNetworkTypeFyber), + @"appodeal": @(AppsFlyerAdRevenueMediationNetworkTypeAppodeal), + @"Admost": @(AppsFlyerAdRevenueMediationNetworkTypeAdmost), + @"Topon": @(AppsFlyerAdRevenueMediationNetworkTypeTopon), + @"Tradplus": @(AppsFlyerAdRevenueMediationNetworkTypeTradplus), + @"Yandex": @(AppsFlyerAdRevenueMediationNetworkTypeYandex), + @"Saturchartboostday": @(AppsFlyerAdRevenueMediationNetworkTypeChartBoost), + @"Unity": @(AppsFlyerAdRevenueMediationNetworkTypeUnity), + @"toponpte": @(AppsFlyerAdRevenueMediationNetworkTypeToponPte), + @"customMediation": @(AppsFlyerAdRevenueMediationNetworkTypeCustom), + @"directMonetizationNetwork": @(AppsFlyerAdRevenueMediationNetworkTypeDirectMonetization) + }; + + NSNumber *enumValueNumber = stringToEnumMap[mediationNetworkString]; + if (enumValueNumber) { + return (AppsFlyerAdRevenueMediationNetworkType)[enumValueNumber integerValue]; + } else { + return -1; + } +} + +/** +* log AdRevenue event +*/ +- (void)logAdRevenue:(CDVInvokedUrlCommand*)command +{ + if ([command.arguments count] == 0) { + return; + } + + NSDictionary* afAdRevenueDataMap = [command argumentAtIndex:0 withDefault:[NSNull null]]; + NSDictionary* additionalParametersMap = [command argumentAtIndex:1 withDefault:[NSNull null]]; + + id monetizationNetwork = nil; + AppsFlyerAdRevenueMediationNetworkType mediationNetwork; + id currencyIso4217Code = nil; + NSNumber *revenue = 0; + + id monetizationNetworkValue = nil; + id mediationNetworkValue = nil; + id currencyIso4217CodeValue = nil; + id revenueValue = nil; + + if(![afAdRevenueDataMap isKindOfClass:[NSNull class]]){ + monetizationNetworkValue = [afAdRevenueDataMap objectForKey:@"monetizationNetwork"]; + if (monetizationNetworkValue != nil && [monetizationNetworkValue isKindOfClass:[NSString class]]) { + monetizationNetwork = monetizationNetworkValue; + } + + mediationNetworkValue = [afAdRevenueDataMap objectForKey:@"mediationNetwork"]; + if (mediationNetworkValue != nil && [mediationNetworkValue isKindOfClass:[NSString class]]) { + if([self getEnumValueFromString: mediationNetworkValue] != -1){ + mediationNetwork = [self getEnumValueFromString: mediationNetworkValue]; + } + else{ + NSLog(@"mediationNetwork param is not according to the Enum format"); + return; + } + } + + currencyIso4217CodeValue = [afAdRevenueDataMap objectForKey:@"currencyIso4217Code"]; + if (currencyIso4217CodeValue != nil && [currencyIso4217CodeValue isKindOfClass:[NSString class]]) { + currencyIso4217Code = currencyIso4217CodeValue; + } + + revenueValue = [afAdRevenueDataMap objectForKey:@"revenue"]; + if (revenueValue != nil && [revenueValue isKindOfClass:[NSNumber class]]) { + revenue = revenueValue; + } + if(monetizationNetwork != nil && currencyIso4217Code != nil && revenue != nil){ + AFAdRevenueData *adRevenueData = [[AFAdRevenueData alloc] initWithMonetizationNetwork:monetizationNetwork mediationNetwork:mediationNetwork currencyIso4217Code:currencyIso4217Code eventRevenue:revenue]; + if([additionalParametersMap isKindOfClass:[NSNull class]]){ + [[AppsFlyerLib shared] logAdRevenue:adRevenueData additionalParameters:nil]; + } + else{ + [[AppsFlyerLib shared] logAdRevenue:adRevenueData additionalParameters:additionalParametersMap]; + } + } + else{ + NSLog(@"one or more arguments are invalid or nil"); + } + } + else{ + NSLog(@"afAdRevenueDataMap is invalid or nil"); + } +} + + /** * Sets new currency code. currencyId: ISO 4217 Currency Codes. */ diff --git a/www/AppsFlyerError.js b/www/AppsFlyerError.js index 9f832e12..d0a1716a 100644 --- a/www/AppsFlyerError.js +++ b/www/AppsFlyerError.js @@ -1,5 +1,3 @@ - - module.exports = Object.freeze({ INVALID_ARGUMENT_ERROR: "INVALID ARGUMENT ERROR", NO_DEVKEY_FOUND: "AppsFlyer 'devKey' is missing or empty", diff --git a/www/appsflyer.js b/www/appsflyer.js index 2d6fe85b..4190d0de 100644 --- a/www/appsflyer.js +++ b/www/appsflyer.js @@ -11,7 +11,29 @@ if (!window.CustomEvent) { }; } + + (function (global) { + + // Enum definition for MediationNetwork + global.MediationNetwork = Object.freeze({ + IRONSOURCE: "ironsource", + APPLOVIN_MAX: "applovinmax", + GOOGLE_ADMOB: "googleadmob", + FYBER: "fyber", + APPODEAL: "appodeal", + ADMOST: "Admost", + TOPON: "Topon", + TRADPLUS: "Tradplus", + YANDEX: "Yandex", + CHARTBOOST: "chartboost", + UNITY: "Unity", + TOPON_PTE: "toponpte", + CUSTOM_MEDIATION: "customMediation", + DIRECT_MONETIZATION_NETWORK: "directMonetizationNetwork" + }); + + var AppsFlyer = function () { }; @@ -37,6 +59,7 @@ if (!window.CustomEvent) { }; })(); + /** * initialize the SDK. * args: SDK configuration @@ -109,6 +132,14 @@ if (!window.CustomEvent) { exec(null, null, 'AppsFlyerPlugin', 'setCurrencyCode', [currencyId]); }; + /** + * Public API - logAdRevenue function + */ + AppsFlyer.prototype.logAdRevenue = function(afAdRevenueData, additionalParameters) { + argscheck.checkArgs('OO', 'AppsFlyer.logAdRevenue', arguments); + exec(null, null, 'AppsFlyerPlugin', 'logAdRevenue', [afAdRevenueData, additionalParameters]); + }; + /** * Setting your own Custom ID enables you to cross-reference your own unique ID with AppsFlyer’s user ID and the other devices’ IDs. */