In order for us to provide optimal support, we would kindly ask you to submit any issues to support@appsflyer.com
When submitting an issue please specify your AppsFlyer sign-up (account) email , your app ID , production steps, logs, code snippets and any additional relevant information.
- integration
- Usage
- Manual start mode
- API methods
- setIsDebug
- stop
- sharingFilter [Deprecated]
- sharingFilterForAllPartners [Deprecated]
- logEvent
- getConversion Listener
- setUserEmails
- setCustomerUserID
- setCurrencyCode
- waitForATTUserAuthorizationWithTimeoutInterval (ios only)
- disableAdvertiserIdentifier
- setShouldCollectDeviceName(ios only)
- setAppInviteOneLink
- anonymizeUser opt-out
- disableCollectASA(ios only)
- setUseReceiptValidationSandbox (ios olny)
- setUseUninstallSandbox (ios only)
- validateAndLogInAppPurchase
- getAppsFlyerUID
- handleOpenURL Deep-linking (ios only)
- Uninstall
- setHost
- setMinTimeBetweenSessions
- deep linking Logging
- generateInviteLink - TBD
- logCrossPromotionImpression - TBD
- logAndOpenStore - TBD
- Unified deep linking
- setPartnerData
- setOneLinkCustomDomain
- setCurrentDeviceLanguage (ios only)
- setSharingFilterForPartners
- setDisableNetworkData (android only)
- Send consent for DMA compliance
- Android AppsFlyer SDK v6.13.0
- iOS AppsFlyer SDK v6.13.1
This is the minimum requirement to start measuring your app installs and is already implemented in this plugin. You MUST modify this call and provide: -devKey - Your application devKey provided by AppsFlyer. -appId - (For iOS only) Your iTunes Application ID.
Add the following lines into applicationDidFinishLaunching
and to applicationWillEnterForeground
method to be able to initialize measuring with your own AppsFlyer dev key:
#include "AppsFlyer/AppsFlyerX.h"
bool AppDelegate::applicationDidFinishLaunching() {
AppsFlyerX::setAppsFlyerDevKey("YOUR_DEV_KEY");
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
AppsFlyerX::setAppleAppID("942960987");
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
AppsFlyerX::start();
#endif
}
void AppDelegate::applicationWillEnterForeground() {
//..
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
AppsFlyerX::start();
#endif
}
Also notify AppsFlyer SDK about background event:
void AppDelegate::applicationDidEnterBackground() {
//...
AppsFlyerX::didEnterBackground();
}
Starting version 6.13.0, we support a manual mode to seperate the initialization of the AppsFlyer SDK and the start of the SDK. In this case, the AppsFlyer SDK won't start automatically, giving the developer more freedom when to start the AppsFlyer SDK. Please note that in manual mode, the developer is required to implement the API start() in order to start the SDK.
If you are using CMP to collect consent data this feature is needed. See explanation here.
bool AppDelegate::applicationDidFinishLaunching() {
...
AppsFlyerX::setAppsFlyerDevKey("devkey");
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
// In case you want to use manual mode.
AppsFlyerX::setManualStart(true);
//
AppsFlyerX::setAppleAppID("appleAppId");
...
}
- See that we aren't calling any AppsFlyerX::start() in any case. The init function is called in the background in order to catch any deeplinking.
And to start the AppsFlyer SDK:
//In case you use manual mode
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
AppsFlyerX::setManualStart(false);
#endif
AppsFlyerX::start();
//
if true
AppsFlyer SDK will run in debug mode
Example:
AppsFlyerX::setIsDebug(true);
if true
AppsFlyer SDK will enter to pending mode, no activity
Be sure to set stop(false)
to release the SDK from stop measuring events
Example:
AppsFlyerX::stop(false); // or false
Use to prevent sharing data with some (one or more) networks/integrated partners.
parameter | type | description |
---|---|---|
eventName |
std::vector<std::string> |
list of partners |
Example:
std::vector<std::string> partners;
partners.push_back("facebook_int");
partners.push_back("googleadwords_int");
AppsFlyerX::sharingFilter(partners);
Use to prevent sharing data with all networks/integrated partners.
Example:
AppsFlyerX::sharingFilterForAllPartners();
- These in-app events help you track how loyal users discover your app, and attribute them to specific campaigns/media-sources. Please take the time define the event/s you want to measure to allow you to track ROI (Return on Investment) and LTV (Lifetime Value).
- The
logEvent
method allows you to send in-app events to AppsFlyer analytics. This method allows you to add events dynamically by adding them directly to the application code.
parameter | type | description |
---|---|---|
eventName |
string |
custom event name, is presented in your dashboard. See the Event list HERE |
eventValues |
cocos2d::ValueMap |
event details |
Example:
//basic implementation
AppsFlyerX::logEvent(AFEventPurchase, {{ "key1", cocos2d::Value("value1")},
{ "key2", cocos2d::Value("value2")}});
//rich in-app-event implementation:
AppsFlyerX::logEvent(AFEventPurchase, {
{ AFEventParamContentId, Value({Value("12344"), Value("98844"), Value("39944")})},
{ AFEventParamCurrency, Value({Value(20), Value(11), Value(61)})},
{ AFEventParamPrice, Value({Value(25), Value(50), Value(10)})},
{ AFEventParamContentType, Value("ELECTRONIC")},
{ AFEventParamCurrency, Value("USD")},
{AFEventParamRevenue, cocos2d::Value("10.67")}
});
More info about rich in-app-events you can find HERE
AppsFlyer allows you to access the user attribution data in real-time directly at SDK level. It enables you to customize the landing page a user sees on the very first app open after a fresh app install.
To access AppsFlyer's conversion data from the Android SDK implement the ConversionDataListener callback:
Examples:
static void onConversionDataReceived(cocos2d::ValueMap installData) {}
static void onConversionDataRequestFailure(cocos2d::ValueMap map) {
/*has signature {
{"status": "failure"},
{"data", "errorMessage"}
}*/
}
static void onAppOpenAttribution(cocos2d::ValueMap map) {}
static void onAppOpenAttributionFailure(cocos2d::ValueMap map) {
/*has signature {
{"status": "failure"},
{"data", "errorMessage"}
}*/
}
AppsFlyerX::setOnConversionDataReceived(onConversionDataReceived);
AppsFlyerX::setOnConversionDataRequestFailure(onConversionDataRequestFailure);
AppsFlyerX::setOnAppOpenAttribution(onAppOpenAttribution);
AppsFlyerX::setOnAppOpenAttributionFailure(onAppOpenAttributionFailure);
AppsFlyer enables you to report one or more of the device’s associated email addresses. You must collect the email addresses and report it to AppsFlyer according to your required encryption method. The following encryption methods are available: SHA1, MD5, SHA256 and plain.
parameter | type | Default | description |
---|---|---|---|
userEmails |
std::vector<std::string> |
--- | list of emails |
type |
EmailCryptTypeX |
--- | crypt type: None, sha1, sha256, md5 |
Examples:
AppsFlyerX::setUserEmails({"kinzer.appsf@gmail.com"}, XEmailCryptTypeSHA256);
Setting your own Custom ID enables you to cross-reference your own unique ID with AppsFlyer’s user ID and the other devices’ IDs. This ID is available in AppsFlyer CSV reports along with postbacks APIs for cross-referencing with you internal IDs.
Note: The ID must be set during the first launch of the app at the SDK initialization. The best practice is to call this API during the deviceready
event, where possible.
parameter | type | description |
---|---|---|
customerUserId |
const std::string& |
Example:
AppsFlyerX::customerUserId("<USER_ID>");
parameter | type | Default | description |
---|---|---|---|
currencyId |
const std::string& |
USD |
ISO 4217 Currency Codes |
Examples:
AppsFlyerX::setCurrencyCode("<CURRENCY_ID>");
parameter | type | Default | description |
---|---|---|---|
timeoutInterval |
double |
See additional info HERE |
parameter | type | Default | description |
---|---|---|---|
flag |
bool |
false |
disables AdvertiserIdentifier |
Examples:
AppsFlyerX::disableAdvertiserIdentifier(true);
parameter | type | Default | description |
---|---|---|---|
flag |
bool |
false |
enables/disables device name tracking |
Examples:
AppsFlyerX::setShouldCollectDeviceName(true);
parameter | type | Default | description |
---|---|---|---|
appInviteOneLinkID |
std::string& |
Before calling start in your app, set the OneLink which is invoked according to the OneLink ID. See additional info HERE |
Examples:
AppsFlyerX::setAppInviteOneLink("8eOw");
parameter | type | Default | description |
---|---|---|---|
flag |
bool |
false |
AppsFlyer provides you a method to opt-out specific users from AppsFlyer analytics. This method complies with the latest privacy requirements and complies with Facebook data and privacy policies. Default is false. Warning Opting out users SEVERELY hurts your attribution information. Use this option ONLY on regions which legally bind you from collecting your users' information. |
Examples:
AppsFlyerX::anonymizeUser(true);
parameter | type | Default | description |
---|---|---|---|
flag |
bool |
false |
enables/disables collect ASA |
Examples:
AppsFlyerX::disableCollectASA(true);
parameter | type | Default | description |
---|---|---|---|
flag |
bool |
false |
enables Receipt Validation Sandbox |
Examples:
AppsFlyerX::setUseReceiptValidationSandbox(true);
parameter | type | Default | description |
---|---|---|---|
flag |
bool |
false |
enables Uninstall Sandbox mode |
Examples:
AppsFlyerX::setUseUninstallSandbox(true);
parameter | type | Default | description |
---|---|---|---|
publicKey |
const std::string& |
||
signature |
const std::string& |
||
purchaseData |
const std::string& |
||
price |
const std::string& |
||
currency |
const std::string& |
||
additionalParameters |
cocos2d::ValueMap |
Examples:
ValueMap test_map;
test_map["key1"] = "value1";
std::string base64EncodedPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3dkBTr2pD2YSqSK2ewlEWwH9Llu0iA4PkwgVOyNRxOsHfrOlqi0Cm51qdNS0aqh/SMZkuQTAroqH3pAr9gVFOiejKRw+ymTaL5wB9+5n1mAbdeO2tv2FDsbawDvp7u6fIBejYt7Dtmih+kcu707fEO58HZWqgzx9qSHmrkMZr6yvHCtAhdBLwSBBjyhPHy7RAwKA+PE+HYVV2UNb5urqIZ9eI1dAv3RHX/xxHVHRJcjnTyMAqBmfFM+o31tp8/1CxGIazVN8HpVk8Qi2uqSS5HdKUu6VnIK8VuAHQbXQn4bG6GXx5Tp0SX1fKrejo7hupNUCgOlqsYHFYxsRkEOi0QIDAQAB";
std::string signature = "OaIdwQOcmrJrMKUx+URVy1I6aeKYiYzflkk1zIKVSs+dDv691neCbR+jlDDzVi3jfSkfirxQISxo7Pe1uzoYbpq9wBk/pMgVjjSbpvCojhA4d/Mwsf4mtAH2LJcVNjhMQdSWvGJlzva3OSt+KQ+9/pRJ15aYT2gFn3SpGSPxNxJmHPIOlM1Lr74MejVu9rnbcSjCB/oI0W4O58p9UWSt5MgmlpqlrK5YqTi1a1VnttY9r1IXFeltwZvmPbcWcYwRHFvemwYGX86huSOFBOYRfaYo9f+DinpoUoXKQEo0JrvKD2/dzFkbUTto1d2OPo1ddaYllgsb2UEV5wwFZFnemg==";
std::string purchaseData = "{\"orderId\":\"\",\"packageName\":\"com.appsflyer.testapp\",\"productId\":\"consumable\",\"purchaseTime\":1497531638107,\"purchaseState\":0,\"developerPayload\":\"2497525891514-5765886608164763986\",\"purchaseToken\":\"pfkalmpnnimamdllmincaida.AO-J1OymunlPCkDQZTf8bPcesoB0n1_ND3WFynoU91-v_R1Px46m3Q-DdRKNlxMVsP2pCTKpo1et1w1IpNVXQ8-zNpRo6a2nXP7a5fQWiDv2asL1dwJPCV8NghDHbstO084IlKo6xcgy\"}";
AppsFlyerX::validateAndLogInAppPurchase(base64EncodedPublicKey,
signature,
"3.00",
"ILS",
test_map);
parameter | type | Default | description |
---|---|---|---|
productIdentifier |
const std::string& |
||
price |
const std::string& |
||
currency |
const std::string& |
||
tranactionId |
const std::string& |
||
params |
cocos2d::ValueMap |
||
successBlock |
std::function<void(cocos2d::ValueMap)> |
||
failureBlock |
std::function<void(cocos2d::ValueMap)> |
Examples:
ValueMap test_map;
test_map["key1"] = "value1";
std::string productIdentifier = "com.mycomp.inapppurchase.cons";
std::string tr_id = "1000000256672208";
AppsFlyerX::validateAndLogInAppPurchase(productIdentifier,
"1.99",
"USD",
tr_id
test_map,
successBlock,
failureBlock);
Examples:
std::string appsflyerId = AppsFlyerX::getAppsFlyerUID();
void AppsFlyerX::handleOpenURL(const std::string& url, const std::string& sourceApplication)
void AppsFlyerX::handleOpenURL(std::string url, std::string sourceApplication, void* annotation)
void AppsFlyerX::handleOpenURL(std::string url, cocos2d::ValueMap options)
Examples:
TBD
Examples:
AppsFlyerX::registerUninstall("<TOKEN>");
For more Info see the DOCs
You can use the registerUninstall(void* deviceToken, unsigned long length)
API.
or
As alternative way use directly native API:
Open your Xcode project and locate the file AppController.mm
under the iOS folder inside your project. Add the following code snippet under didFinishLaunchingWithOptions
:
#import "AppsFlyerLib.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//...
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
//..
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[[AppsFlyerLib shared] registerUninstall:deviceToken];
}
and method implementation:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[[AppsFlyerLib shared] registerUninstall:deviceToken];
}
parameter | type | Default | description |
---|---|---|---|
host |
std::string& |
host name that should override appsflyer.com |
|
Examples: |
AppsFlyerX::setHost("mynewhost.com");
parameter | type | Default | description |
---|---|---|---|
minTimeBetweenSessions |
unsigned long |
host name that should override appsflyer.com |
|
Examples: |
AppsFlyerX::setMinTimeBetweenSessions(9);
Allows to pass GCM/FCM Tokens that where collected by third party plugins to the AppsFlyer server. Can be used for Uninstall measuring.
parameter | type | description |
---|---|---|
token |
String |
GCM/FCM Token |
In ver. >4.2.5 deeplinking metadata (scheme/host) is sent automatically TBD
TBD
#import "AppsFlyerLib.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//...
AppsFlyerX::setDidResolveDeepLink(didResolveDeepLink);
//..
}
static void didResolveDeepLink(AppsFlyerXDeepLinkResult result){
CCLOG("%s", "AppDelegate.cpp got ddl!");
std::string ddl = "Deep link data is \n";
switch (result.status) {
case NOTFOUND:
CCLOG("deep link not found");
break;
case FOUND:
if (!result.deepLink.empty()){
if (!result.getMediaSource().empty()) {
CCLOG("Media source is %s", result.getMediaSource().c_str());
}
for (auto &t : result.deepLink){
CCLOG("%s - %s", t.first.c_str(), t.second.asString().c_str());
ddl.append(t.first.c_str());
ddl.append(" : ");
ddl.append(t.second.asString().c_str());
ddl.append("\n");
}
}
}
}
}
Partners and advertisers can add more data in SDK events.
parameter | type | description |
---|---|---|
partnerId |
String |
partner identifier |
data |
cocos2d::ValueMap |
data to add |
ValueMap data;
data["thePartnerId"] = "abcd";
data["Item_id"] = 1;
data["isLegacy"] = false;
AppsFlyerX::setPartnerData("partnerID", data);
Use to get conversion data with Branded links.
parameter | type | description |
---|---|---|
domains |
std::vector<std::string> |
list of custom domains |
Example:
std::vector<std::string> domains;
domains.push_back("test.domain.com");
domains.push_back("myDomain.com");
AppsFlyerX::setOneLinkCustomDomain(domains);
Use to get conversion data with Branded links.
parameter | type | description |
---|---|---|
language |
std::string |
Language to set |
Example:
AppsFlyerX::setCurrentDeviceLanguage("English");
Used by advertisers to set some (one or more) networks/integrated partners to exclude from getting data.
parameter | type | description |
---|---|---|
partners |
std::vector<std::string> |
partners to exclude from getting data |
Example:
std::vector<std::string> partners;
partners.push_back("partners_1");
AppsFlyerX::setSharingFilterForPartners(partners); // Single partner
std::vector<std::string> partners;
partners.push_back("partners_1");
partners.push_back("partners_2");
AppsFlyerX::setSharingFilterForPartners(partners); // Multiple partner
std::vector<std::string> partners;
partners.push_back("all");
AppsFlyerX::setSharingFilterForPartners(partners); // All partners
std::vector<std::string> partners;
partners.push_back("");
AppsFlyerX::setSharingFilterForPartners(partners); // Reset list (default)
std::vector<std::string> partners;
AppsFlyerX::setSharingFilterForPartners(partners); // Reset list (default)
Use to opt-out of collecting the network operator name (carrier) and sim operator name from the device.
parameter | type | description |
---|---|---|
disable |
bool |
Defaults to false |
Example:
AppsFlyerX::setDisableNetworkData(true);
Integration guide Migration guide In v6 of AppsFlyer SDK there are some api breaking changes:
Before v6 | v6 |
---|---|
trackAppLaunch | start |
trackEvent | logEvent |
trackLocation | logLocation |
stopTracking | stop |
validateAndTrackInAppPurchase | validateAndLogInAppPurchase |
setDeviceTrackingDisabled | anonymizeUser |
on iOS you need to implement IDFA request pop up and add AppTrackTransparency framework in order for the plugin to work
For a general introduction to DMA consent data, see here.
The SDK offers two alternative methods for gathering consent data:
- Through a Consent Management Platform (CMP): If the app uses a CMP that complies with the Transparency and Consent Framework (TCF) v2.2 protocol, the SDK can automatically retrieve the consent details.
OR - Through a dedicated SDK API: Developers can pass Google's required consent data directly to the SDK using a specific API designed for this purpose.
A CMP compatible with TCF v2.2 collects DMA consent data and stores it in SharedPreferences
(Android) or NSUserDefaults
(iOS). To enable the SDK to access this data and include it with every event, follow these steps:
- Call
AppsFlyerX::enableTCFDataCollection(true)
to instruct the SDK to collect the TCF data from the device. - Set the the adapter to be manual(see (#manual-start)[manual mode]).
This will allow us to delay the Conversion call to provide the SDK with the user consent. - Use the CMP to decide if you need the consent dialog in the current session.
- If needed, show the consent dialog, using the CMP, to capture the user consent decision. Otherwise, go to step 6.
- Get confirmation from the CMP that the user has made their consent decision, and the data is available in
SharedPreferences
orNSUserDefaults
. - Call start the following way:
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) AppsFlyerX::setManualStart(false); #endif AppsFlyerX::start();
bool AppDelegate::applicationDidFinishLaunching() {
AppsFlyerX::stop(false);
AppsFlyerX::enableTCFDataCollection(true);
AppsFlyerX::setIsDebug(true);
AppsFlyerX::setAppsFlyerDevKey("devkey");
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
// In case you want to use manual mode.
AppsFlyerX::setManualStart(true);
//
AppsFlyerX::setAppleAppID("appleAppId");
- after getting CMP results
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
AppsFlyerX::setManualStart(false);
#endif
AppsFlyerX::start();
If your app does not use a CMP compatible with TCF v2.2, use the SDK API detailed below to provide the consent data directly to the SDK.
- Initialize
AppsFlyerX
using manual mode. This will allow us to delay the Conversion call in order to provide the SDK with the user consent. - Determine whether the GDPR applies or not to the user.
- If GDPR applies to the user, perform the following:- Given that GDPR is applicable to the user, determine whether the consent data is already stored for this session.
- If there is no consent data stored, show the consent dialog to capture the user consent decision.
- If there is consent data stored continue to the next step.
- To transfer the consent data to the SDK create an object called
AppsFlyerXConsent
using theforGDPRUser()
method with the following parameters:
-hasConsentForDataUsage
- Indicates whether the user has consented to use their data for advertising purposes.
-hasConsentForAdsPersonalization
- Indicates whether the user has consented to use their data for personalized advertising purposes. - Call
AppsFlyerX::setConsentData()
with theAppsFlyerXConsent
object. - Call start:
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) AppsFlyerX::setManualStart(false); #endif AppsFlyerX::start();
- If GDPR doesn’t apply to the user perform the following:- Create an
AppsFlyerXConsent
object using theforNonGDPRUser()
method. This method doesn’t accept any parameters. - Call
AppsFlyerX::setConsentData()
with theAppsFlyerXConsent
object. - Call start:
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) AppsFlyerX::setManualStart(false); #endif AppsFlyerX::start();
- Given that GDPR is applicable to the user, determine whether the consent data is already stored for this session.