At a glance: Integrate and install the AppsFlyer SDK into Android or iOS apps developed with Unity. Once basic integration tasks are complete, your app is ready for install attribution and in-app event measurement.
Related reading
For a complete picture of integrating the Unity plugin with your apps, be sure to read these articles:
- Unity plugin V6 integration guide—Overview
- Unity plugin V6 integration guide—Basic SDK integration (this article)
- Unity plugin V6 integration guide—Additional SDK integration
- Unity plugin V6 integration guide—API reference
Add the plugin to your app
Important!
AppsFlyer Unity SDK doesn't support Unity Internal Build System.
Download the AppsFlyer Unity plugin
Download the latest Unity plugin from GitHub.
Install the plugin
Use one of the following installation methods.
The External Dependency Manager for Unity (EDM4U) is distributed with the AppsFlyer Unity plugin by default. This eases the integration process by resolving dependency conflicts between your plugin and other plugins in your project.
To install the plugin:
Add appsflyer-unity-plugin.v*.unitypackage to automatically import all the assets required for both the AppsFlyer plugin and the EDM4U.
To install the plugin without the EDM4U:
- Import appsflyer-unity-plugin.v*.unitypackage to your project, but make sure to clear the selection of EDM4U dependencies.
- Download and add the required Android dependencies to the Assets/Plugins/Android folder:
- Download and add the required iOS dependencies to the Assets/Plugins/iOS/AppsFlyer folder:
Set up Android
To set up the required Android permissions:
Set the following permissions in AndroidManifest.xml
:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Apps targeting API level 31 (Android 12) should add the following permission to AndroidManifest.xml
to access the Android Advertising Identifier:
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
Initialize the plugin
This section describes how to implement and initialize the plugin.
Retrieve the dev key
- The key is unique and identifies the account. In some cases there is an app-level key.
- Dev key is mandatory.
To get the dev key:
- In AppsFlyer, go to Configuration > App Settings.
- Get the dev key.
Initialize the plugin
To initialize the plugin using the prefab:
- Go to Assets > AppsFlyer.
- Drag AppsFlyerObject.prefab to your scene.
- Set the following fields:
Setting Remarks Dev key Paste the dev key that you retrieved previously. App ID iOS: Enter the iOS app ID (no
id
prefix).Android: Leave blank.
Get conversion data If the app implements AppsFlyer deep linking, set to "True". The default is "False', meaning deep linking by default is NOT implemented. Is debug To view debug logs during development: Set to true.
Note: Ensure to disable (set to false) before releasing the app to production.
- Update the code in Assets > AppsFlyer > AppsFlyerObjectScript.cs with other available APIs.
To integrate manually:
Create a game object and add the following init code:
using AppsFlyerSDK;
public class AppsFlyerObjectScript : MonoBehaviour , IAppsFlyerConversionData
{
void Start()
{
/* AppsFlyer.setDebugLog(true); */
AppsFlyer.initSDK("devkey", "appID", this);
AppsFlyer.startSDK();
}
public void onConversionDataSuccess(string conversionData)
{
AppsFlyer.AFLog("onConversionDataSuccess", conversionData);
Dictionary<string, object> conversionDataDictionary = AppsFlyer.CallbackStringToDictionary(conversionData);
// add deferred deeplink logic here
}
public void onConversionDataFail(string error)
{
AppsFlyer.AFLog("onConversionDataFail", error);
}
public void onAppOpenAttribution(string attributionData)
{
AppsFlyer.AFLog("onAppOpenAttribution", attributionData);
Dictionary<string, object> attributionDataDictionary = AppsFlyer.CallbackStringToDictionary(attributionData);
// add direct deeplink logic here
}
public void onAppOpenAttributionFailure(string error)
{
AppsFlyer.AFLog("onAppOpenAttributionFailure", error);
}
}
Note: Make sure not to call destroy on the game object.
Record in-app events
Record in-app events to measure KPIs such as revenue, ROI, and LTV (Lifetime Value).
In-app events should be implemented to record user events. Events can be sent in several ways:
- [Best practice] Sending events via the app as described in this article.
- For additional methods see the in-app events overview guide.
For apps that belong to a vertical, for example, travel, gaming, eCommerce, see the list of recommended in-app events per vertical.
In-app event names and parameters
To send events:
- Specify the event name and parameters.
- See related lists:
- List of recommended event names and structures
- List found in
AFInAppEvents
class.
[Best practice] Use event names and parameters for the following reasons:
- Standard naming: AppsFlyer can automatically map events to SRNs such as Meta ads, Google, and Twitter.
- Backward compatibility: No issue arises if AppsFlyer changes an event name or parameter. The implementation is backward compatible.
Record revenue
Report revenue by adding the af_revenue
parameter to in-app events.
- Populate
af_revenue
with numeric values. Negative values are permitted. - The
af_revenue
parameter populates AppsFlyer revenue counters and raw data fields. Doing so enables marketers to view revenue in the dashboard. - Revenue can be sent using other parameters, but the AppsFlyer platform won't recognize it as revenue. Click here for more details.
- Revenue values must not contain comma separators, currency symbols, or text.
Example revenue event: 1234.56
Best practice: Learn about currency settings, display, and currency conversion.
Currency code requirements when sending revenue events
- Default currency: USD
- Use a 3-character ISO 4217 code (an example follows).
- Set the currency code by calling the API:
AppsFlyer.setCurrencyCode("ZZZ")
Example: In-app purchase event with revenue
This purchase event is for 200.12 Euros. For the revenue to reflect in the dashboard use the following.
System.Collections.Generic.Dictionary<string, string> purchaseEvent = new
System.Collections.Generic.Dictionary<string, string> ();
purchaseEvent.Add(AFInAppEvents.CURRENCY, "EUR");
purchaseEvent.Add(AFInAppEvents.REVENUE, "200.12");
purchaseEvent.Add(AFInAppEvents.QUANTITY, "1");
purchaseEvent.Add(AFInAppEvents.CONTENT_TYPE, "category_a",);
AppsFlyer.sendEvent ("af_purchase", purchaseEvent);
Record negative revenue
Record negative revenue using a minus sign.
- Revenue value is preceded by a minus sign.
- The event name has a unique value, "cancel_purchase". This lets you identify negative revenue events in raw data reports and in the Dashboard.
Example: App user receives a refund or cancels a subscription.
System.Collections.Generic.Dictionary<string, string> purchaseEvent = new
System.Collections.Generic.Dictionary<string, string> ();
purchaseEvent.Add(AFInAppEvents.CURRENCY, "USD");
purchaseEvent.Add(AFInAppEvents.REVENUE, "-200");
purchaseEvent.Add(AFInAppEvents.QUANTITY, "1");
purchaseEvent.Add(AFInAppEvents.CONTENT_TYPE, "category_a");
AppsFlyer.sendEvent ("cancel_purchase", purchaseEvent);
In-app purchase validation
The plugin provides server verification for in-app purchases.
To validate a purchase, operating system specific instructions:
#if UNITY_ANDROID && !UNITY_EDITOR
AppsFlyerAndroid.validateAndSendInAppPurchase(
"publicKey",
"signature",
"purchaseData",
"price",
"currency",
null,
this);
#endif
Ensure you test against the Apple sandbox server call:
#if UNITY_IOS && !UNITY_EDITOR
AppsFlyeriOS.validateAndSendInAppPurchase(
"productIdentifier",
"price",
"currency",
"tranactionId",
null,
this);
#endif
Method parameters
Parameter | Description |
---|---|
String publicKey | Public key from Google Developer Console |
String signature |
Transaction signature; returned by Google API when a purchase is completed |
String purchaseData |
Product purchased in JSON format; returned by Google API when a purchase is completed |
String revenue | In-app event revenue to be reported to AppsFlyer |
String currency | In-app event currency to be reported to AppsFlyer |
Dictionary<String, String> additionalParameters |
Additional in-app event parameters which appear in the event_value field in in-app event raw data |
Parameter | Description |
---|---|
String productIdentifier | Product identifier |
String price | In-app event revenue to be reported to AppsFlyer |
String currency | In-app event currency to be reported to AppsFlyer |
Dictionary<String, String> additionalParameters |
Additional in-app event parameters which appear in the event_value field in in-app event raw data |
Note
Call validateReceipt
to automatically generate an af_purchase in-app event.
Don't send a purchase event after validating the purchase. Doing so results in duplicate event reporting.
In-app event considerations
- Event name: maximum 45 characters
- Event value: must not exceed 1000 characters - if longer we can truncate it
- Supports non-English characters for in-app events (and other APIs)
- Pricing and revenue:
- Only use numbers and decimals such as 5 or 5.2
- Up to 5 numbers after the decimal are permitted. For example, 5.12345
Examples of recording in-app events
Record in-app events by calling sendEvent
and include the event name and value parameters.
See In-app events for more details.
Example: How to record an in-app purchase event
For a comprehensive list of ready-made code snippets per vertical, see our guides for rich in-app events per verticals.
System.Collections.Generic.Dictionary<string, string> purchaseEvent = new
System.Collections.Generic.Dictionary<string, string> ();
purchaseEvent.Add(AFInAppEvents.CURRENCY, "USD");
purchaseEvent.Add(AFInAppEvents.REVENUE, "200");
purchaseEvent.Add(AFInAppEvents.QUANTITY, "2");
purchaseEvent.Add(AFInAppEvents.CONTENT_TYPE, "category_a");
purchaseEvent.Add(AFInAppEvents.CONTENT_ID, "092");
AppsFlyer.sendEvent (AFInAppEvents.PURCHASE, purchaseEvent);
Record offline in-app events
Sometimes users generate in-app events, while they have no internet connection. AppsFlyer caches the event and reports when possible.
- The plugin sends events to AppsFlyer servers and waits for a response.
- If the plugin doesn’t get a 200 response, the event is stored in the cache.
- After receiving the next 200 response, the cached event is re-sent to the server.
- If the cache holds multiple events, they are sent to the server one after the other.
Note
The cache can store up to 40 events.
- Only the first 40 offline events are saved.
- All following offline events, up until the next 200 response, are discarded.
- In the raw data report,
- Event time = when an event was sent to AppsFlyer after the device is back online.
- It is not the time when the event took place.
Deep-link with OneLink
AppsFlyer OneLink is the solution for multi-platform attribution: redirection and deep linking.
Device detection and redirection
OneLink:
- Detects the device type (Android and iOS, desktop, etc.) when a user clicks, then
- Redirects the user to the correct destination: Google Play, iOS app store, out-of-store markets, or web pages.
To implement multi-platform attribution links and review the basics of deep linking, see the OneLink redirection guide.
Deep linking
Use deep linking to direct existing users to specific activities and customized content.
An app owner and a developer must work together to set up deep linking with OneLink:
- App owner must access the AppsFlyer dashboard
- Developer must access the app
Deferred deep linking
Deferred deep linking lets you deep link new users to direct them to specific activities and customized content with the first launch after an app install.
Standard deep linking also directs users to specific activities and customized content, but an app must already be installed on the user's device.
To set up deferred deep linking with OneLink:
- Developer needs access to the AppsFlyer platform.
- AppsFlyer platform setup for deferred and standard deep linking is the same.
- Must implement additional logic in the app to deep link users and provide them with customized content after they install and launch the app.
Check deferred deep linking for more information.
Get deep link data
The plugin provides conversion or engagement data after every install or deep-linking event. Use this data to customize content or the app's programmatic behavior.
To receive deep link data:
- Implement callback
onAppOpenAttribution
(found inIAppsFlyerConversionData
class); it is called by the AppsFlyer plugin. - Returned OneLink/attribution link parameters trigger an app to open.
- Parse the values and apply the logic to trigger the relevant app page.
public void onAppOpenAttribution(string attributionData)
{
AppsFlyer.AFLog("onAppOpenAttribution", attributionData);
Dictionary<string, object> attributionDataDictionary = AppsFlyer.CallbackStringToDictionary(attributionData);
// add direct deeplink logic here
}
Check deep linking data for more information.
Get conversion data
Access to real-time user attribution data is available for each install. Use this to enhances user engagement by providing:
- Personalized content
- Sending users to specific activities within an app. See deferred deep linking in this article.
Obtain AppsFlyer conversion data
To obtain AppsFlyer conversion data:
- Implement the
IAppsFlyerConversionDatabase
. - Call the
initSDK
method with this as the last parameter. - Use the
onConversionDataSuccess
method to redirect the user.
See API reference for onConversionDataSuccess.
using AppsFlyerSDK;
public class AppsFlyerObjectScript : MonoBehaviour , IAppsFlyerConversionData
{
void Start()
{
/* AppsFlyer.setDebugLog(true); */
AppsFlyer.initSDK("devkey", "appID", this);
AppsFlyer.startSDK();
}
public void onConversionDataSuccess(string conversionData)
{
AppsFlyer.AFLog("onConversionDataSuccess", conversionData);
Dictionary<string, object> conversionDataDictionary = AppsFlyer.CallbackStringToDictionary(conversionData);
// add deferred deeplink logic here
}
public void onConversionDataFail(string error)
{
AppsFlyer.AFLog("onConversionDataFail", error);
}
public void onAppOpenAttribution(string attributionData)
{
AppsFlyer.AFLog("onAppOpenAttribution", attributionData);
Dictionary<string, object> attributionDataDictionary = AppsFlyer.CallbackStringToDictionary(attributionData);
// add direct deeplink logic here
}
public void onAppOpenAttributionFailure(string error)
{
AppsFlyer.AFLog("onAppOpenAttributionFailure", error);
}
}
Test installs
Allowlist the test device
Allowlist the test device.
Simulate installs
Simulate organic and non-organic installs.
Simulate an organic install
Organic installs are unattributed installs; they are usually the result of installs made directly via app stores. To simulate an organic install, follow these instructions.
Simulate a non-organic install
Non-organic installs are attributed installs; they are usually the result of an ad engagement. To simulate a non-organic install, follow these instructions.