> ## Documentation Index
> Fetch the complete documentation index at: https://help.airbridge.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Unity SDK (Deprecated)

![Maven metadata URL](https://img.shields.io/maven-metadata/v?metadataUrl=https%3A%2F%2Fsdk-download.airbridge.io%2Funity%2Fmetadata.xml\&versionPrefix=1\&label=Airbridge%20Unity%20SDK)

## Install SDK

<Info>
  **Note**

  The Airbridge Unity SDK requires Unity version 2018.4 or later.
</Info>

<Danger>
  **Attention**

  The Airbridge Unity SDK uses the Unity Jar Resolver, the External Dependency Manager for Unity, to manage library dependencies.

  For Airbridge Unity SDK v1.9.2 and earlier, the following setup is required.

  1. Set up the Unity package by referring to the repository below.
     * [Unity Jar Resolver Repository](https://github.com/googlesamples/unity-jar-resolver)

  2. Set up the EDM4U by referring to the setup guide below.
     * [EDM4U Setup Guide](https://airbridge.readme.io/v1.1-en/docs/edm4u-setup-guide)

  For Airbridge Unity SDK v.1.9.3 and later, the above setup is unnecessary as the SDK automatically imports all Airbridge plugins and EDM4U assets.
</Danger>

### Install package

1. Download the latest version of the [Airbridge Unity SDK](https://sdk-download.airbridge.io/unity/airbridge-unity-1.17.1.unitypackage).
2. Navigate to **\[Assets] >\[Import Package]>\[Custom Package...]** in Unity and add the package file.
3. The **\[AB180]** tab will appear in the top menu bar once the package is installed.

### Set up project

Navigate to **\[AB180]>\[Airbridge Settings]** in the top menu bar to open the following screen.

<Frame>
  <img src="https://mintcdn.com/airbridge-help-center/Tr8kwyIK5qm-uvmV/asset/image/unity-airbridge-settings.png?fit=max&auto=format&n=Tr8kwyIK5qm-uvmV&q=85&s=4e1945b4c221a4bff0f6e5dd5dbdc5dc" alt="01-en-dev-unity-sdk" width="1284" height="712" data-path="asset/image/unity-airbridge-settings.png" />
</Frame>

<Danger>
  **Attention**

  After filling out the fields, click **Update iOS App Setting** or **Update Android Manifest** to apply changes.
</Danger>

<Danger>
  **Attention**

  If you want to manually merge the `Android Manifest` file, navigate to **\[Project]>\[Plugins]>\[Airbridge]>\[Android]** and refer to the `AndroidManifest.xml` file.
</Danger>

#### Set up app information

In the Airbridge dashboard, navigate to **\[Settings]>\[Tokens]** and copy the **App Name** and **Token**.

<Frame>
  <img src="https://mintcdn.com/airbridge-help-center/6CTRFgWYblklSTQJ/asset/image/app-sdk-token-settings.png?fit=max&auto=format&n=6CTRFgWYblklSTQJ&q=85&s=8ac768ed162169aa315cbd8e7255de92" alt="02-en-dev-unity-sdk" width="1500" height="956" data-path="asset/image/app-sdk-token-settings.png" />
</Frame>

Then, go to Unity, navigate to **\[AB180]>\[Airbridge Settings]** in the top menu bar, and paste the App Name and App Token into the respective fields.

#### Initialization

The Airbridge Unity SDK does not require initialization. However, in particular cases, a migration process may be required per platform.

#### Set up Application Entry Point

<Frame>
  <img src="https://mintcdn.com/airbridge-help-center/Tr8kwyIK5qm-uvmV/asset/image/unity-android-application-entry-point.png?fit=max&auto=format&n=Tr8kwyIK5qm-uvmV&q=85&s=c43fc50926a48af4e14c13f9be43046d" alt="unity-android-application-entry-point" width="1402" height="704" data-path="asset/image/unity-android-application-entry-point.png" />
</Frame>

When using the Unity version 2023.1 or later, you can navigate to **\[Android Player Settings]>\[Other Settings]>\[Configuration]>\[Application Entry Point]** and set the "Application Entry Point" to **Activity**, **GameActivity**, or **Activity and Game Activity**. Refer to the information below to learn about the additional configurations that are required depending on how the "Application Entry Point" is set.

<AccordionGroup>
  <Accordion title="If the Application Entry Point is set to Activity">
    The Android Manifest file is automatically updated with the value entered in the **\[AB180]>\[Airbridge Settings]**, and therefore, no action is required.
  </Accordion>

  <Accordion title="If the Application Entry Point is set to GameActivity">
    ###### v1.16.3 or later

    The Android Manifest file is automatically updated with the value entered in the **\[AB180]>\[Airbridge Settings]**, and therefore, no action is required.

    ###### v1.16.2 or earlier

    The custom Activity provided by the Airbridge Unity SDK is an Activity that inherits from com.unity3d.player.UnityPlayerActivity, and therefore, the following actions are required.

    1. Remove the  `Assets/Plugins/Airbridge/Android/java/co/ab180/airbridge/unity/AirbridgeActivity.java` file.
    2. Create a Custom Activity file (`AirbridgeGameActivity.java`) as follows.

    ```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    package co.ab180.airbridge.unity;
    import android.content.Intent;
    import android.os.Bundle;
    import com.unity3d.player.UnityPlayerGameActivity;
    public class AirbridgeGameActivity extends UnityPlayerGameActivity {
        @Override
        protected void onCreate(Bundle bundle) {
            super.onCreate(bundle);
        }
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            setIntent(intent);
        }
        @Override
        protected void onResume() {
            super.onResume();
            AirbridgeUnity.processDeeplinkData(getIntent());
        }
    }
    ```

    3. Register the Custom Activity as follows in the Android Manifest file (`{UNITY_PROJECT}/Plugins/Android/AndroidManifest.xml`).

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <?xml version="1.0" encoding="utf-8"?>
    <manifest
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
        <application>
            <activity android:name="co.ab180.airbridge.unity.AirbridgeGameActivity"
                android:theme="@style/BaseUnityGameActivityTheme"
                android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
                <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
                <meta-data android:name="android.app.lib_name" android:value="game" />
            </activity>
        </application>
    </manifest>
    ```
  </Accordion>

  <Accordion title="If the Application Entry Point is set to Activity and GameActivity">
    <Danger>
      **Attention**

      For development purposes, you can set up 2 application entry points.

      <Frame>
        <img src="https://mintcdn.com/airbridge-help-center/Tr8kwyIK5qm-uvmV/asset/image/unity-application-entry-points.png?fit=max&auto=format&n=Tr8kwyIK5qm-uvmV&q=85&s=39fe28f963eb82da543d165b2aae0169" alt="unity-android-2-application-entries" width="321" height="72" data-path="asset/image/unity-application-entry-points.png" />
      </Frame>
    </Danger>

    ###### v1.16.3 or later

    1. Refer to the `AirbridgeActivity.java.template` file and `AirbridgeGameActivity.java.template` file located inside the `{UNITY_PROJECT}/Plugins/Airbridge/Android/java/co/ab180/airbridge/unity` folder to create your activities.
    2. Apply each activity to your Android Manifest file.
    3. The Android Manifest file will then be automatically updated with the values set in the **\[AB180]>\[Airbridge Settings]**.

    ###### v1.16.2 or earlier

    Airbridge Unity SDK does not provide a custom Activity that inherits from com.unity3d.player.UnityPlayerGameActivity, and [setting the Intent Filter](/en/developers/deprecated-android-sdk-v2#set-up-intent-filter) to the value set in the ["AB180 → Airbridge Settings"](#project-setup) is only automatic for one Activity, so the following additional work is required.

    1. Create a Custom Activity file (`AirbridgeGameActivity.java`) as follows.

    ```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    package co.ab180.airbridge.unity;
    import android.content.Intent;
    import android.os.Bundle;
    import com.unity3d.player.UnityPlayerGameActivity;
    public class AirbridgeGameActivity extends UnityPlayerGameActivity {
        @Override
        protected void onCreate(Bundle bundle) {
            super.onCreate(bundle);
        }
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            setIntent(intent);
        }
        @Override
        protected void onResume() {
            super.onResume();
            AirbridgeUnity.processDeeplinkData(getIntent());
        }
    }
    ```

    2. Set the Android Manifest file (`{UNITY_PROJECT}/Plugins/Android/AndroidManifest.xml`) as follows.

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <?xml version="1.0" encoding="utf-8"?>
    <manifest
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
        <application>
            <!--Used when Application Entry is set to Activity, otherwise remove this activity block-->
            <activity android:name="co.ab180.airbridge.unity.AirbridgeActivity"
                      android:theme="@style/UnityThemeSelector"
                      android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
                <intent-filter android:autoVerify="true">
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <data android:scheme="http" android:host="YOUR_APP_NAME.abr.ge" />
                    <data android:scheme="https" android:host="YOUR_APP_NAME.abr.ge" />
                </intent-filter>
                <intent-filter android:autoVerify="true">
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <data android:scheme="http" android:host="YOUR_APP_NAME.airbridge.io" />
                    <data android:scheme="https" android:host="YOUR_APP_NAME.airbridge.io" />
                </intent-filter>
                <intent-filter>
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <data android:scheme="YOUR_APP_URI_SCHEME" />
                </intent-filter>
                <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
            </activity>
            <!--Used when Application Entry is set to GameActivity, otherwise remove this activity block-->
            <activity android:name="co.ab180.airbridge.unity.AirbridgeGameActivity"
                      android:theme="@style/BaseUnityGameActivityTheme"
                      android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
                <intent-filter android:autoVerify="true">
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <data android:scheme="http" android:host="YOUR_APP_NAME.abr.ge" />
                    <data android:scheme="https" android:host="YOUR_APP_NAME.abr.ge" />
                </intent-filter>
                <intent-filter android:autoVerify="true">
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <data android:scheme="http" android:host="YOUR_APP_NAME.airbridge.io" />
                    <data android:scheme="https" android:host="YOUR_APP_NAME.airbridge.io" />
                </intent-filter>
                <intent-filter>
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <data android:scheme="YOUR_APP_URI_SCHEME" />
                </intent-filter>
                <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
                <meta-data android:name="android.app.lib_name" android:value="game" />
            </activity>
        </application>
    </manifest>
    ```

    * `YOUR_APP_NAME`: **App Name** set in the **\[AB180]>\[Airbridge Settings]** at the top menu bar in Unity
    * `YOUR_APP_URI_SCHEME`: Android URI Scheme set in the **\[AB180]>\[Airbridge Settings]** at the top menu bar in Unity
  </Accordion>
</AccordionGroup>

If you did not set the Application Entry Point, follow the guides below to complete the setup.

* For Unity version 6, refer to the [GameActivity guide](#set-to-gameactivity).
* For Unity versions earlier than version 6, refer to the [Activity guide](#set-to-activity).

### SDK testing

After completing the Airbridge Unity SDK setup, you can test whether it works properly by following the methods below.

#### Using the Airbridge Dashboard

<Frame>
  <img src="https://mintcdn.com/airbridge-help-center/6CTRFgWYblklSTQJ/asset/image/app-real-time-logs-sdk-events.png?fit=max&auto=format&n=6CTRFgWYblklSTQJ&q=85&s=8f2aeca7c1045a430c89eb8ca54acc2a" alt="03-en-dev-unity-sdk" width="1500" height="956" data-path="asset/image/app-real-time-logs-sdk-events.png" />
</Frame>

1. Install and open the app on a test device.
2. Navigate to **\[Raw Data]>\[App Real-time Logs]** in the Airbridge dashboard.
3. Enter the [Google Advertising ID](https://developer.android.com/training/articles/ad-id) (GAID) of the test device to find it in the logs.

It may take up to 5 minutes for the logs to be visible in the dashboard.

<Danger>
  **Attention**

  It may take up to 5 minutes for the logs to appear on the \[Real-time Logs] page.
</Danger>

#### Using the logs

<Frame>
  <img src="https://mintcdn.com/airbridge-help-center/yb7Ud8MfVkimM8iI/asset/image/unity-log-level-debug.png?fit=max&auto=format&n=yb7Ud8MfVkimM8iI&q=85&s=6956e240095c4f576b8c595c9be2f73c" alt="03-kr-dev-unity-sdk" width="1075" height="404" data-path="asset/image/unity-log-level-debug.png" />
</Frame>

Navigate to **\[AB180]>\[Airbridge Settings]** in Unity and check the Log Level.

## Deep Linking

### Set up dashboard

Refer to the guides below to set up the Airbridge dashboard for deep linking.

* [Dashboard setup guide for iOS](/en/developers/deprecated-ios-sdk-v1#set-up-dashboard)
* [Dashboard setup guide for Android](/en/developers/deprecated-android-sdk-v2#set-up-dashboard)

### Set up project

#### iOS

Navigate to **\[AB180]>\[Airbridge Settings]** in Unity and enter the **iOS URI Scheme**, which can be found on the **\[Tracking Link]>\[Deep Links]** page in the Airbridge dashboard.

<Frame>
  <img src="https://mintcdn.com/airbridge-help-center/6CTRFgWYblklSTQJ/asset/image/android-deep-link-certificate-fingerprint.png?fit=max&auto=format&n=6CTRFgWYblklSTQJ&q=85&s=f83c7b3e2a0da8a98a0b723bec82c6f0" alt="04-en-dev-unity-sdk" width="1500" height="956" data-path="asset/image/android-deep-link-certificate-fingerprint.png" />
</Frame>

#### Android

Navigate to **\[AB180]>\[Airbridge Settings]** in Unity and enter the **Android URI Scheme**, which can be found on the **\[Tracking Link]>\[Deep Links]** page in the Airbridge dashboard.

<Frame>
  <img src="https://mintcdn.com/airbridge-help-center/6CTRFgWYblklSTQJ/asset/image/android-uri-scheme-setting.png?fit=max&auto=format&n=6CTRFgWYblklSTQJ&q=85&s=5c70352a4b681910266995de13fb7b33" alt="05-en-dev-unity-sdk" width="1500" height="956" data-path="asset/image/android-uri-scheme-setting.png" />
</Frame>

#### Set up a custom domain

When generating tracking links in the Airbridge dashboard, you can use tracking links in the form of `deeplink.page` or `abr.ge`. However, for branding purposes and to improve click-through rates (CTR), you can use customized URLs as tracking links, such as `go.my_company.com/abcd`, by following the steps below.

1. Set up the custom domain in the Airbridge dashboard by referring to this [user guide](/en/guides/custom-domain).
2. Navigate to **\[AB180]>\[Airbridge Settings]** in Unity and enter the custom domain.

<Frame>
  <img src="https://mintcdn.com/airbridge-help-center/Tr8kwyIK5qm-uvmV/asset/image/unity-custom-domain.png?fit=max&auto=format&n=Tr8kwyIK5qm-uvmV&q=85&s=33fee58d7f4bb5dda5f12abb3d683795" alt="unity custom domain legacy" width="1383" height="448" data-path="asset/image/unity-custom-domain.png" />
</Frame>

#### Set up deep link callback

To receive the deep link data clicked by the user, register the object name using `SetDeeplinkCallback` to receive messages like below.

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
private void Awake()
{
    AirbridgeUnity.SetDeeplinkCallback("AirbridgeManager");
}
```

Airbridge will receive the deep link URL once `SetDeeplinkCallback` is set as above.

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
using UnityEngine;

public class AirbridgeManager : MonoBehaviour
{ 
  private void Awake() {
    AirbridgeUnity.SetDeeplinkCallback("AirbridgeManager");
  }
  
  // Method will call by Airbridge when deeplink detected
  private void OnTrackingLinkResponse(string url)
  {

  }
}
```

<Note>
  The Airbridge Unity SDK uses Unity's `UnitySendMessage` method to forward deep link information.
</Note>

### Deep link testing

Click on your URI scheme to test if your deep link has been properly set up in the Airbridge SDK.

* `YOUR_APP_URI_SCHEME://`

When the deep link setup is successful, you will see the Deeplink Open event on the **\[Raw Data]>\[App Real-time Log]** page in the Airbridge dashboard, like in the following image.

<Frame>
  <img src="https://mintcdn.com/airbridge-help-center/6CTRFgWYblklSTQJ/asset/image/app-real-time-logs-deep-link-event.png?fit=max&auto=format&n=6CTRFgWYblklSTQJ&q=85&s=dcdfd5780b41a7682b2d43975de94f25" alt="06-en-dev-unity-sdk" width="1500" height="705" data-path="asset/image/app-real-time-logs-deep-link-event.png" />
</Frame>

## User Data

### User identifier

To measure the fragmented contributions of users between web and app, Airbridge collects the following user identifier information.

* User Email: Email address
* User Phone: Phone number
* User ID: Unique User ID (The ID value that specifies the user must be the same in both web and mobile)
* User Alias: Identifiers that can represent users (e.g. loyalty program ID, affiliate integrated ID, etc)

<Note>
  The user's email and phone numbers are hashed (SHA256) by default and then sent to servers.
</Note>

You can set the user identifier as below for the SDK.

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
Dictionary<string, string> alias = new Dictionary<string, string>();
AirbridgeUser user = new AirbridgeUser();
user.SetId("personID");
user.SetEmail("persondoe@airbridge.io");
user.SetPhoneNumber("1(123)123-1234");
user.SetAlias("key", "value");
AirbridgeUnity.SetUser(user);
```

| Name        | Description       | Limitations                                                                                                                                                                     |
| ----------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Id          | User ID           | -                                                                                                                                                                               |
| Email       | User email        | Hashed by default<br />(SHA256, can be disabled)                                                                                                                                |
| PhoneNumber | User phone number | Hashed by default<br />(SHA256, can be disabled)                                                                                                                                |
| Alias       | User alias        | - Maximum 10 aliases<br />- `key`type is String, maximum 128 characters<br />- `key`must satisfy `^[a-z_][a-z0-9_]*$`regex<br />- `value`type is String, maximum 128 characters |

Once the user identifier has been configured, all events will be forwarded with the corresponding identity information.

<Danger>
  **Attention**

  The user identifier properties can be reset or overwritten through user events.
</Danger>

### User Attribute

Additional user attributes can be used for more accurate Multi-Touch Attribution (MTA) analyses, additional internal data analyses, and linking third-party solutions.

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
Dictionary<string, object> attrs = new Dictionary<string, object>();
AirbridgeUser user = new AirbridgeUser();
user.SetAttributes("key", "value");
AirbridgeUnity.SetUser(user);
```

| Name       | Description    | Limitations                                                                                                                                                                                                                       |
| ---------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Attributes | User attribute | - Maximum 100 attributes<br />- "key" type is string, maximum 128 characters<br />- "key" must satisfy `^[a-z_][a-z0-9_]*$`regex<br />- "value" type is primitive or string<br />- Maximum 1024 characters when "value" is string |

<Danger>
  **Attention**

  The user identifier properties can be reset or overwritten through user events.
</Danger>

### Testing

Make sure that your user information settings are being properly sent through the SDK.

1. Configure user identifier information.
2. Send an event using the SDK.
3. Click the event at "Airbridge dashboard → Raw Data → App Real-time Logs"
4. Check if the user information is correctly sent under the `user`block.

<Frame>
  <img src="https://mintcdn.com/airbridge-help-center/6CTRFgWYblklSTQJ/asset/image/app-real-time-logs-user-details.png?fit=max&auto=format&n=6CTRFgWYblklSTQJ&q=85&s=4c1917b29aa2e20722f5aec384f9145c" alt="07-en-dev-unity-sdk" width="1500" height="702" data-path="asset/image/app-real-time-logs-user-details.png" />
</Frame>

## Device Setup

### Setup Device Alias

Setup a device alias through the Airbridge SDK. The alias will be sustained even after the app closes, unless otherwise deleted.

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
AirbridgeUnity.SetDeviceAlias("ADD_YOUR_KEY", "AND_YOUR_VALUE");
AirbridgeUnity.RemoveDeviceAlias("DELETE_THIS_KEY");
AirbridgeUnity.ClearDeviceAlias();
```

| SetDeviceAlias(string key, string value) | Add the key value pair to the device identifier. |
| ---------------------------------------- | ------------------------------------------------ |
| RemoveDeviceAlias(string key)            | Delete the corresponding device alias.           |
| ClearDeviceAlias()                       | Delete all device aliases.                       |

## Event Setup

When important user actions occur, in-app events can be sent to measure performance by channel.

All event parameters are optional. However, more information about the event will help provide a more accurate analysis.

All events called by the Airbridge SDK can be sent with the following fields.

| Name                      | Type                        | Description                    |
| ------------------------- | --------------------------- | ------------------------------ |
| Event Category            | String                      | Name of the event **Required** |
| Event Action              | String                      | Event attribute 1              |
| Event Label               | String                      | Event attribute 2              |
| Event Value               | Float                       | Event attribute value          |
| Event Custom Attributes   | Dictionary\<string, object> | Custom attributes              |
| Event Semantic Attributes | Dictionary\<string, object> | Semantic attributes            |

### Standard Events

Send standard user events with the SDK.

`action`, `label`, `value`, `attributes` can also be used when sending standard events.

#### Sign Up

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
Dictionary<string, string> alias = new Dictionary<string, string>();
AirbridgeUser user = new AirbridgeUser();
user.SetId(UserId);
user.SetEmail(Email);
user.SetPhoneNumber(Phone);
user.SetAlias(alias);
AirbridgeUnity.SetUser(user);

AirbridgeEvent @event = new AirbridgeEvent(Airbridge.Constants.CATEGORY.SIGN_UP);
AirbridgeUnity.TrackEvent(@event);
```

#### Sign In

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
Dictionary<string, string> alias = new Dictionary<string, string>();
AirbridgeUser user = new AirbridgeUser();
user.SetId(UserId);
user.SetEmail(Email);
user.SetPhoneNumber(Phone);
user.SetAlias(alias);
AirbridgeUnity.SetUser(user);

AirbridgeEvent @event = new AirbridgeEvent(Airbridge.Constants.CATEGORY.SIGN_IN);
AirbridgeUnity.TrackEvent(@event);
```

#### Sign Out

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
AirbridgeEvent @event = new AirbridgeEvent(Airbridge.Constants.CATEGORY.SIGN_OUT);
AirbridgeUnity.TrackEvent(@event);
AirbridgeUnity.ExpireUser();
```

<Danger>
  **Attention**

  All user identifier properties will disappear after `sign out` is called.
</Danger>

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
Airbridge.Ecommerce.Product cocacola = new Airbridge.Ecommerce.Product();
cocacola.SetId("beverage_1");
cocacola.SetName("Coca Cola");
cocacola.SetPrice(1.25);
cocacola.SetCurrency("USD");
cocacola.SetQuantity(1);
cocacola.SetPosition(0);
```

#### View Home Screen

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
AirbridgeEvent @event = new AirbridgeEvent(Airbridge.Constants.CATEGORY.VIEW_HOME);
AirbridgeUnity.TrackEvent(@event);
```

#### View Search Result

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
List<Airbridge.Ecommerce.Product> beverages = new List<Airbridge.Ecommerce.Product>();
Airbridge.Ecommerce.Product cocacola = new Airbridge.Ecommerce.Product();
cocacola.SetId("beverage_1");
cocacola.SetName("Coca Cola");
cocacola.SetPrice(1.25);
cocacola.SetCurrency("USD");
cocacola.SetQuantity(1);
cocacola.SetPosition(0);
beverages.Add(cocacola);

Airbridge.Ecommerce.Product fanta = new Airbridge.Ecommerce.Product();
fanta.SetId("beverage_2");
fanta.SetName("Fanta");
fanta.SetPrice(10.99);
fanta.SetCurrency("USD");
fanta.SetQuantity(1);
fanta.SetPosition(1);
beverages.Add(fanta);

AirbridgeEvent @event = new AirbridgeEvent(Airbridge.Constants.CATEGORY.VIEW_SEARCH_RESULT);
@event.SetQuery("SELECT * FROM beverages");
@event.SetProducts(beverages.ToArray());
@event.SetValue(12.24);
@event.SetCurrency("USD");
AirbridgeUnity.TrackEvent(@event);
```

#### View Product List

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
List<Airbridge.Ecommerce.Product> beverages = new List<Airbridge.Ecommerce.Product>();
Airbridge.Ecommerce.Product cocacola = new Airbridge.Ecommerce.Product();
cocacola.SetId("beverage_1");
cocacola.SetName("Coca Cola");
cocacola.SetPrice(1.25);
cocacola.SetCurrency("USD");
cocacola.SetQuantity(1);
cocacola.SetPosition(0);
beverages.Add(cocacola);

Airbridge.Ecommerce.Product fanta = new Airbridge.Ecommerce.Product();
fanta.SetId("beverage_3");
fanta.SetName("Fanta");
fanta.SetPrice(10.99);
fanta.SetCurrency("USD");
fanta.SetQuantity(1);
fanta.SetPosition(2);
beverages.Add(fanta);

AirbridgeEvent @event = new AirbridgeEvent(Airbridge.Constants.CATEGORY.VIEW_PRODUCT_LIST);
@event.SetProductListId("beverage_list_0");
@event.SetProducts(beverages.ToArray());
@event.SetValue(12.24);
@event.SetCurrency("USD");
AirbridgeUnity.TrackEvent(@event);
```

#### View Product Detail

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
Airbridge.Ecommerce.Product cocacola = new Airbridge.Ecommerce.Product();
cocacola.SetId("beverage_1");
cocacola.SetName("Coca Cola");
cocacola.SetPrice(1.25);
cocacola.SetCurrency("USD");
cocacola.SetQuantity(1);
cocacola.SetPosition(0);

AirbridgeEvent @event = new AirbridgeEvent(Airbridge.Constants.CATEGORY.VIEW_PRODUCT_DETAILS);
@event.SetProducts(cocacola);
@event.SetCurrency("USD");
AirbridgeUnity.TrackEvent(@event);
```

#### Add To Cart

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
Airbridge.Ecommerce.Product cocacola = new Airbridge.Ecommerce.Product();
cocacola.SetId("beverage_1");
cocacola.SetName("Coca Cola");
cocacola.SetPrice(1.25);
cocacola.SetCurrency("USD");
cocacola.SetQuantity(1);
cocacola.SetPosition(0);

AirbridgeEvent @event = new AirbridgeEvent(Airbridge.Constants.CATEGORY.ADDED_TO_CART);
@event.SetProducts(cocacola);
@event.SetCurrency("USD");
@event.SetValue(1.25);
AirbridgeUnity.TrackEvent(@event);
```

#### Purchase

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
List<Airbridge.Ecommerce.Product> beverages = new List<Airbridge.Ecommerce.Product>();
Airbridge.Ecommerce.Product cocacola = new Airbridge.Ecommerce.Product();
cocacola.SetId("beverage_1");
cocacola.SetName("Coca Cola");
cocacola.SetPrice(1.25);
cocacola.SetCurrency("USD");
cocacola.SetQuantity(1);
cocacola.SetPosition(0);
beverages.Add(cocacola);

Airbridge.Ecommerce.Product fanta = new Airbridge.Ecommerce.Product();
fanta.SetId("beverage_3");
fanta.SetName("Fanta");
fanta.SetPrice(10.99f);
fanta.SetCurrency("USD");
fanta.SetQuantity(1);
fanta.SetPosition(2);
beverages.Add(fanta);

AirbridgeEvent @event = new AirbridgeEvent(Airbridge.Constants.CATEGORY.ORDER_COMPLETED);
@event.SetTransactionId("transaction_123");
@event.SetProducts(beverages.ToArray());
@event.SetCurrency("USD");
@event.SetInAppPurchased(true);
@event.SetValue(1.25);
AirbridgeUnity.TrackEvent(@event);
```

### Custom Events

Send custom events with the SDK.

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
AirbridgeEvent @event = new AirbridgeEvent("category");
@event.SetAction("action");
@event.SetLabel("label");
@event.SetValue(9999);
@event.AddCustomAttribute("custom_key", "value");
@event.AddSemanticAttribute("query", "query_123");
AirbridgeUnity.TrackEvent(@event);
```

<Note>
  To configure and deliver `Semantic Attributes` directly, please refer to this [guide](/en/developers/event-structure#semantic-attributes).
</Note>

### Verify Event Transmission

Make sure that the events are being properly sent through the SDK.

1. Send an event with the SDK.
2. Check if the event shows up at "Airbridge dashboard → Raw Data → App Real-time Logs".

<Frame>
  <img src="https://mintcdn.com/airbridge-help-center/6CTRFgWYblklSTQJ/asset/image/app-real-time-logs-event-list.png?fit=max&auto=format&n=6CTRFgWYblklSTQJ&q=85&s=4b82a73077ddc330be51a6fc826ddc09" alt="08-en-dev-unity-sdk" width="1500" height="702" data-path="asset/image/app-real-time-logs-event-list.png" />
</Frame>

## Advanced Setup

***

### SDK Signature Setup

Protection against SDK spoofing is possible once you input the "SDK Signature Secret ID" and "SDK Signature Secret" values in the "AB180 -> Airbridge Settings menu".

<Note>
  The SDK Signature Credentials are required for the SDK Signature setup. Refer to this [article](/en/guides/sdk-signature#configuring-the-sdk-signature-credentials) to learn how to create them.
</Note>

### Hash User Identifier

Email addresses and phone numbers are hashed by default. (SHA256)

Settings can be changed by configuring the "User Info Hash Enabled" field at "AB180 → Airbridge Settings".

<Danger>
  **Attention**

  Other security measures must be taken internally when sensitive personal information such as "User Email" and "User Phone" is being handled.
</Danger>

### Session Timeout Setup

The Airbridge Unity SDK does not send app open events again if the user reopens the app within the time configured at the "Session Timeout Seconds" field at "AB180 → Airbridge Settings".

Session timeout is in milliseconds and must range between 0 and 604800000 (7 days).

The default value is 1000 \* 60 \* 5 (5 minutes).

### Setting up Opt-In

This feature is useful for conducting data collection and transmission in compliance with [GDPR](https://gdpr-info.eu/) or [CCPA](https://oag.ca.gov/privacy/ccpa).

You can explicitly start data collection and transmission by navigating to `AB180` > `Airbridge Settings` in the top menu bar of Unity, and selecting the `Auto Start Tracking Enabled` field.

When this feature is disabled, the following function must be explicitly called for proper data collection.

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
AirbridgeUnity.StartTracking();
```

### Setting up Opt-Out

<Note>
  **Attention**

  The instructions below are optional. Proceed only if necessary.
</Note>

Opt-Out is a policy where user information is used until the user refuses.

After setting `setAutoStartTrackingEnabled` to `true`, call the `stopTracking` function at the point where events cannot be collected. From the point when the `stopTracking` function is called, events are not collected.

<CodeGroup>
  ```c# C# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  AirbridgeUnity.stopTracking();
  ```
</CodeGroup>

### Track Airbridge Link Only

If it is difficult to see the performance of re-engagement through Airbridge at a glance due to too many deep link actions within the advertiser's app, "Track Airbridge Link Only" field at "AB180 → Airbridge Settings" can be used to only filter results received through Airbridge deep links.

This option will measure deep links only if the following requirements are met.

* The app is opened through a `airbridge.io`link
* The app is opened through a `deeplink.page`link
* The app is opened through a [Custom Domain Setup](/en/developers/deprecated-android-sdk-v2#custom-domain-setup) that is registered on the Airbridge dashboard
* The app is opened through a link that contains `airbridge_referrer`information in the query

### Location Collection (Android only)

Airbridge Unity SDK can collect user location information through the "Location Collection Enabled" field at "AB180 → Airbridge Settings"

<Danger>
  **Attention**

  Location information must be collected for legal purposes through legal methods.
</Danger>

### Facebook Deferred App Links

You can receive Facebook Deferred App Links from the Airbridge Unity SDK through by configuring "Facebook Deferred App Link Enabled" at "AB180 → Airbridge Settings".

<Danger>
  **Attention**

  The Facebook SDK setting must be installed in advance to use this feature.

  See - [https://developers.facebook.com/docs/unity/](https://developers.facebook.com/docs/unity/)
</Danger>

### Tracking Authorize Timeout (iOS only)

When the [AppTrackingTransparency.framework](https://developer.apple.com/documentation/apptrackingtransparency) is used to present an app-tracking authorization request to the user, IDFA will not be collected when the install event occurs because the install event occurs before the selection.

The "iOS Tracking Authorize Timeout Seconds" field at "AB180 → Airbridge Settings" allows you to delay the transmission of installation events so that the IDFA value may be included.

### Meta install referrer Collection Setup

Meta install referrer (MIR) Collection Setup supported by Airbridge Unity SDK in version 1.16.1 or higher. To collect data, set as below.

You can pass your Facebook App ID through by configuring "Meta Install Referrer (Facebook App ID)" at "AB180 → Airbridge Settings".

<Frame>
  <img src="https://mintcdn.com/airbridge-help-center/yb7Ud8MfVkimM8iI/asset/image/unity-meta-install-referrer.png?fit=max&auto=format&n=yb7Ud8MfVkimM8iI&q=85&s=d0aefe552217932a14fe1b289d95c4d1" alt="Unity SDK - Meta install referrer Collection Setup - Image" width="839" height="482" data-path="asset/image/unity-meta-install-referrer.png" />
</Frame>

After adding the settings, you must enter the decryption key to see decrypted MIR. Refer to this [article](/en/guides/meta-business-google-play-install-referrer) to learn about MIR.

### Uninstall Tracking

<Note>
  This feature is available for only Unity SDK v1.9.0+.
</Note>

###### Reference

* [Android Uninstall Tracking](/en/developers/uninstall-tracking-deprecated-android-sdk-v2)
* [iOS Uninstall Tracking](/en/developers/uninstall-tracking-deprecated-ios-sdk-v1)

###### Android Uninstall Tracking

**1. Setup Firebase Cloud Messaging**

Please refer to the official [Firebase Cloud Messaging documentation](https://firebase.google.com/docs/cloud-messaging/unity/client) for basic app setup.

**2. Forward Firebase Push Token**

Forward the push token to Airbridge using the `RegisterPushToken` method.

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
public void Start() {
  Firebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived;
  Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
}

public void OnTokenReceived(object sender, Firebase.Messaging.TokenReceivedEventArgs token) {
#if UNITY_ANDROID
  AirbridgeUnity.RegisterPushToken(token.Token);
#endif
}

// Make sure the notification is not shown on the device if the remote message value is airbridge-uninstall-tracking.
public void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e) {
  if (e.Message.Data.ContainsKey("airbridge-uninstall-tracking")) return;
  ...
}
```

###### iOS Uninstall Tracking

**1. Setup Apple Push Notification Service**

Please refer to the official [Unity Mobile Notifications Package documentation](https://docs.unity3d.com/Packages/com.unity.mobile.notifications@2.1/manual/index.html) and install the package.

**2. Forward Device Token**

Forward the device token to Airbridge using the `RegisterPushToken` method.

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
void Start()
{
#if UNITY_IOS
  StartCoroutine(RequestAuthorization());
#endif
}

#if UNITY_IOS
IEnumerator RequestAuthorization()
{
  var authorizationOption = AuthorizationOption.Alert | AuthorizationOption.Badge;
  using (var req = new AuthorizationRequest(authorizationOption, true))
  {
    while (!req.IsFinished)
    {
      yield return null;
    };
    if (req.Granted && req.DeviceToken != "")
    {
      AirbridgeUnity.RegisterPushToken(req.DeviceToken);
    }
  }
}
#endif
```

## Hybrid App Setup

***

Additional events such as app installs, app open,s and deep link opens can't be tracked with just the web SDK. The following simple setup allows in-app events to be called for a hybrid app.

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
AirbridgeWebInterface webInterface;
webInterface = AirbridgeUnity.CreateWebInterface(
    "YOUR_WEB_TOKEN",     // web token
    (msg) => $@"..."      // post command function
);
```

`AirbridgeUnity.CreateWebInterface` allows you to control the web interface.

Please refer to the [Unity Hybrid App Integration Guide](https://airbridge.readme.io/v1.1-en/page/unity-hybrid-app-integration-guide) for more information.

<Danger>
  **Attention**

  Hybrid app setup is available for Airbridge Unity SDK v1.9.3+.
</Danger>

## Troubleshooting

***

### Android

#### Airbridge Unity SDK does not seem to initialize correctly

The Airbridge Unity SDK for Android initializes automatically through [Content Provider](https://developer.android.com/guide/topics/providers/content-provider-basics). For proper initialization, the following XML tag must be correctly placed in "Project → Plugins → Android → AndroidManifest.xml".

```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
<provider
    android:authorities="${applicationId}.co.ab180.airbridge.unity.AirbridgeContentProvider"
    android:name="co.ab180.airbridge.unity.AirbridgeContentProvider"
    android:exported="false" />
```

#### Using your own custom activity class

The Airbridge Unity SDK uses custom activities in "UnityPlayerActivity" to get deep link data. If you are using your own custom activity class, please override the following codes inside your custom activity class.

```java lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
@Override
protected void onNewIntent(Intent intent) {
  super.onNewIntent(intent);
  setIntent(intent);
}

@Override
protected void onResume() {
  super.onResume();
  AirbridgeUnity.processDeeplinkData(getIntent());
}
```

#### The AndroidManifest file does not seem to merge properly

The "AndroidManifest Merger" that the Airbridge Unity SDK provides is a simple component that merges "Project → Plugins → Android → AndroidManifest.xml" and "Project → Plugins → Airbridge → Android → AndroidManifest.xml". The merge may not satisfy all cases, and you will have to separately merge your "AndroidManifest.xml" file with reference to "Project → Plugins → Airbridge → Android → AndroidManifest.xml".

#### Missing 'package' key attribute on element package at ...

Due to the addition of Android 11's [`Package Visibility`](https://developer.android.com/training/package-visibility) policy, applications should be properly informed by `<queries>` inside the `manifest` file about which packages are used in order to properly interact with another applications.

The Airbridge SDK is compliant with the policy and requires Gradle `v5.6.4+` and Android Gradle Plugin `v3.6.0+` to support the `<queries>` tag.

Please refer to this [page](https://docs.unity3d.com/Manual/android-gradle-overview.html) for information on which version of Gradle is used by Unity.

<AccordionGroup>
  <Accordion title="Unity 2020.1 or later">
    No further action is required because the necessary Gradle and Android Gradle plugin exists.
  </Accordion>

  <Accordion title="Unity 2019.3 to 2019.4">
    <Note>
      The following customization is supported only on Unity 2019.3 patch 7 and later.
    </Note>

    1. Go to the [Gradle Build Tool](https://gradle.org/releases) page and download Gradle v5.6.4 or higher
    2. Go to "Preferences → External Tools" to uncheck "Gradle Installed with Unity (recommended)" and set the path to the downloaded Gradle file as below.

    <Frame>
      <img src="https://mintcdn.com/airbridge-help-center/Tr8kwyIK5qm-uvmV/asset/image/unity-external-gradle-path.png?fit=max&auto=format&n=Tr8kwyIK5qm-uvmV&q=85&s=f2beaa64e916c158bc2f26845f467f92" alt="09-en-dev-unity-sdk" width="1226" height="168" data-path="asset/image/unity-external-gradle-path.png" />
    </Frame>

    3. Go to "Project Settings → Player → Android Tab → Publishing Settings → Build" and select the following options:
       1. Custom Main Gradle Template
       2. Custom Launcher Gradle Template

    <Frame>
      <img src="https://mintcdn.com/airbridge-help-center/Tr8kwyIK5qm-uvmV/asset/image/unity-custom-gradle-templates.png?fit=max&auto=format&n=Tr8kwyIK5qm-uvmV&q=85&s=5ad2fb8453952c27ad148e9043d8cd0a" alt="10-en-dev-unity-sdk" width="654" height="322" data-path="asset/image/unity-custom-gradle-templates.png" />
    </Frame>

    4. Please change both of the following auto-generated files as follows
       1. `Assets/Plugins/Android/mainTemplate.gradle`
       2. `Assets/Plugins/Android/launcherTemplate.gradle`

    ```groovy lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    buildscript {
        repositories {
            google()
            jcenter()
        }
        dependencies {
            // Must be Android Gradle Plugin 3.6.0 or later. For a list of
            // compatible Gradle versions refer to:
            // https://developer.android.com/studio/releases/gradle-plugin
            classpath 'com.android.tools.build:gradle:3.6.0'
        }
    }
    allprojects {
       repositories {
          google()
          jcenter()
          flatDir {
            dirs 'libs'
          }
       }
    }
    ```
  </Accordion>

  <Accordion title="Unity 2019.1 to 2019.2">
    1. Go to the [Gradle Build Tool](https://gradle.org/releases) page and download Gradle v5.6.4 or higher.
    2. Go to "Preferences → External Tools" to uncheck "Gradle Installed with Unity (recommended)" and set the path to the downloaded Gradle file as below.

    <Frame>
      <img src="https://mintcdn.com/airbridge-help-center/Tr8kwyIK5qm-uvmV/asset/image/unity-external-gradle-path.png?fit=max&auto=format&n=Tr8kwyIK5qm-uvmV&q=85&s=f2beaa64e916c158bc2f26845f467f92" alt="11-en-dev-unity-sdk" width="1226" height="168" data-path="asset/image/unity-external-gradle-path.png" />
    </Frame>

    3. Go to "Project Settings → Player → Android Tab → Publishing Settings → Build" and select "Custom Gradle Template".

    <Frame>
      <img src="https://mintcdn.com/airbridge-help-center/yb7Ud8MfVkimM8iI/asset/image/unity-main-gradle-template.png?fit=max&auto=format&n=yb7Ud8MfVkimM8iI&q=85&s=8742776966130ceb2c8f7a6d33d906eb" alt="12-en-dev-unity-sdk" width="582" height="140" data-path="asset/image/unity-main-gradle-template.png" />
    </Frame>

    4. Go to the auto generated "Assets/Plugins/Android/MainTemplate.gradle" file and make the following changes.

    ```groovy lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    buildscript {
        dependencies {
            // Must be Android Gradle Plugin 3.6.0 or later. For a list of
            // compatible Gradle versions refer to:
            // https://developer.android.com/studio/releases/gradle-plugin
            classpath 'com.android.tools.build:gradle:3.6.0'
        }
    }
    ```
  </Accordion>

  <Accordion title="Unity 2018.4">
    <Note>
      The following customization is supported only on Unity `2018.4 patch 24` and later
    </Note>

    1. Go to the [Gradle Build Tool](https://gradle.org/releases) page and download Gradle v5.6.4 or higher.
    2. Go to "Build Settings → Android" and set "Build System" to "Gradle" to use a custom version of Gradle.

    <Frame>
      <img src="https://mintcdn.com/airbridge-help-center/Tr8kwyIK5qm-uvmV/asset/image/unity-android-gradle-build-system.png?fit=max&auto=format&n=Tr8kwyIK5qm-uvmV&q=85&s=3a8bc079871ebbdd27f7837573122d9b" alt="13-en-dev-unity-sdk" width="1244" height="324" data-path="asset/image/unity-android-gradle-build-system.png" />
    </Frame>

    3. Go to "Preferences → External Tools", uncheck "Gradle Installed with Unity (recommended)" and set the path to the downloaded "Gradle" file.

    <Frame>
      <img src="https://mintcdn.com/airbridge-help-center/Tr8kwyIK5qm-uvmV/asset/image/unity-external-gradle-path.png?fit=max&auto=format&n=Tr8kwyIK5qm-uvmV&q=85&s=f2beaa64e916c158bc2f26845f467f92" alt="14-en-dev-unity-sdk" width="1226" height="168" data-path="asset/image/unity-external-gradle-path.png" />
    </Frame>

    4. Go to "Project Settings → Player → Android Tab → Publishing Settings → Build" and select the "Custom Gradle Template" option.

    <Frame>
      <img src="https://mintcdn.com/airbridge-help-center/yb7Ud8MfVkimM8iI/asset/image/unity-main-gradle-template.png?fit=max&auto=format&n=yb7Ud8MfVkimM8iI&q=85&s=8742776966130ceb2c8f7a6d33d906eb" alt="15-en-dev-unity-sdk" width="582" height="140" data-path="asset/image/unity-main-gradle-template.png" />
    </Frame>

    5. Go to the auto generated "Assets/Plugins/Android/MainTemplate.gradle" file and make the following changes.

    ```groovy lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    buildscript {
        dependencies {
            // Must be Android Gradle Plugin 3.6.0 or later. For a list of
            // compatible Gradle versions refer to:
            // https://developer.android.com/studio/releases/gradle-plugin
            classpath 'com.android.tools.build:gradle:3.6.0'
        }
    }
    ```
  </Accordion>

  <Accordion title="Unity 2018.3 or earlier">
    Gradle customizations are not supported on these versions of Unity and are not compatible with the necessary changes to support Android 11 (API level 30).
  </Accordion>
</AccordionGroup>

#### Resolve Airbridge SDK backup rules merge conflict issue

* Reference : [Android SDK Auto Backup](/en/developers/deprecated-android-sdk-v2#auto-backup)

If you are experiencing build errors caused by overlapping of the Airbridge SDK backup rules and third-party SDK backup rules, please refer to the workaround below.

e.g) If you have an Airbridge SDK backup rule and an Appsflyer SDK backup rule that overlap, you will see the build error below.

```html lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
Attribute application@fullBackupContent value=(@xml/appsflyer_backup_rules) from [com.appsflyer:af-android-sdk:6.6.1] AndroidManifest.xml:14:18-73
is also present at [io.airbridge:sdk-android:2.14.0] AndroidManifest.xml:27:18-78 value=(@xml/airbridge_auto_backup_rules).
Suggestion: add 'tools:replace="android:fullBackupContent"' to <application> element at AndroidManifest.xml:7:5-13:19 to override.
```

To resolve this issue, please set up as follows.

<AccordionGroup>
  <Accordion title="backup_rules.xml setup">
    1. Create an Android Library project (`Assets/Plugins/Android/res.androidlib`) to store your resource files.
    2. Add an `AndroidManifest.xml` file in the created Android Library Project as follows.

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="custom.android.res"
              android:versionCode="1"
              android:versionName="1.0">
    </manifest>
    ```

    3. Create a `res/xml` folder inside the created Android Library Project.
    4. Create a file (e.g. `custom_backup_rules.xml`) within the created xml folder.
    5. Add the data backup rules defined by the Airbridge SDK as follows.

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <?xml version="1.0" encoding="utf-8"?>
    <full-backup-content>
        <!-- Airbridge Backup Rules -->
        <exclude domain="sharedpref" path="airbridge-internal" />
        <exclude domain="sharedpref" path="airbridge-install" />
        <exclude domain="sharedpref" path="airbridge-user-info" />
        <exclude domain="sharedpref" path="airbridge-user-alias" />
        <exclude domain="sharedpref" path="airbridge-user-attributes" />
        <exclude domain="sharedpref" path="airbridge-device-alias" />
        <exclude domain="database" path="airbridge.db" />
        <!-- Appsflyer Backup Rules -->
        <exclude domain="sharedpref" path="appsflyer-data"/>

        <!-- Your Custom Backup Rules -->
    </full-backup-content>
    ```
  </Accordion>

  <Accordion title="AndroidManifest.xml setup">
    Apply the data backup rules to the Android App Manifest file (`Assets/Plugins/Android/AndroidManifest.xml`) as follows.

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <manifest
        ...
        xmlns:tools="http://schemas.android.com/tools">

        <application
            ...
            android:allowBackup="true"
            android:fullBackupContent="@xml/custom_backup_rules"
            tools:replace="android:fullBackupContent">
    ```
  </Accordion>
</AccordionGroup>

For more guidance, refer to the articles below.

* [Import an Android Library Project](https://docs.unity3d.com/2022.3/Documentation/Manual/android-library-project-import.html)
* [Override the Android App Manifest](https://docs.unity3d.com/2022.3/Documentation/Manual/overriding-android-manifest.html)

### iOS

#### **\[Xcode 27] SceneDelegate Migration Required — Additional Setup Needed for Airbridge Deep Links**

<Note>
  **Attention**

  This troubleshooting guide is for customers who need to migrate an existing AppDelegate-based app to UIScene(SceneDelegate) lifecycle.
</Note>

##### Symptoms

* When an app built with Xcode 27 is launched, the app may not run properly.
* Airbridge deep link events are not collected even when the app is opened through a scheme deep link or Universal Link.
* The app does not work even though the code was added to `AppDelegate`as shown in the [Initialize SDK](/en/developers/react-native-sdk-v4) and [Collect deep link events in your app](/en/developers/react-native-sdk-v4) developer guide examples.

##### Cause

Apple is moving the app lifecycle from the `UIApplicationDelegate`-only AppDelegate model to the `UIScene`-based SceneDelegate model, and adopting the Scene lifecycle has effectively become required in the latest Xcode and iOS environments.

When an app adopts the Scene lifecycle through `UIApplicationSceneManifest`, the following `AppDelegate` deep link callbacks are **no longer called.**

##### Solution

The required steps depend on the Unity Engine and Airbridge SDK versions. Starting with the Unity Engine versions listed below, Unity generates `UnityScene` when creating an Xcode project.

###### Unity versions that support UnityScene

| **2022.3 LTS**           | **`2022.3.72f1`** |
| ------------------------ | ----------------- |
| **6000.0.x (LTS)**       | **`6000.0.75f1`** |
| **6000.1.x \~ 6000.3.x** | **Not supported** |
| **6000.4.x**             | **`6000.4.0f1`**  |
| **6000.5.x**             | **`6000.5.0f1`**  |

Use one of the listed versions or later. If you are using a version that does not support `UnityScene`, you need to add a separate `UIScene`.

###### Versions that do not support UnityScene

In the SceneDelegate file where a UIScene has been added in Unity, call the public deep link interface in `AirbridgeUnity.h`.

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
#import "AirbridgeUnity.h"

@implementation MyUnityScene

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    for (UIOpenURLContext *context in connectionOptions.URLContexts) {
        if (context.URL == nil) {
            continue;
        }

        [AirbridgeUnity.deeplink handleURLSchemeDeeplink:context.URL];
    }

    for (NSUserActivity *userActivity in connectionOptions.userActivities) {
        [AirbridgeUnity.deeplink handleUniversalLink:userActivity.webpageURL];
    }
}

- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
    for (UIOpenURLContext *context in URLContexts) {
        if (context.URL == nil) {
            continue;
        }

        [AirbridgeUnity.deeplink handleURLSchemeDeeplink:context.URL];
    }
}

- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity {
    [AirbridgeUnity.deeplink handleUniversalLink:userActivity.webpageURL];
}

@end
```

###### Versions that support UnityScene

In the `UnityScene` file of the Xcode project generated by Unity, call the public deep link interface in `AirbridgeUnity.h`.

```c# lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
#import "UnityScene.h"
#import "UnityAppController.h"
#import "AirbridgeUnity.h"

@implementation UnityScene

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    for (UIOpenURLContext *context in connectionOptions.URLContexts) {
        if (context.URL == nil) {
            continue;
        }

        [AirbridgeUnity.deeplink handleURLSchemeDeeplink:context.URL];
    }

    for (NSUserActivity *userActivity in connectionOptions.userActivities) {
        [AirbridgeUnity.deeplink handleUniversalLink:userActivity.webpageURL];
    }
}

- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
    for (UIOpenURLContext *context in URLContexts) {
        if (context.URL == nil) {
            continue;
        }

        [AirbridgeUnity.deeplink handleURLSchemeDeeplink:context.URL];
    }
}

- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity {
    [AirbridgeUnity.deeplink handleUniversalLink:userActivity.webpageURL];
}

@end
```

#### Using your own custom AppController

Airbridge Unity SDK uses `IMPL_APP_CONTROLLER_SUBCLASS` to create a custom AppController. If you are using your own custom AppController, add the following code to your custom AppController.

```objective-c lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
- (BOOL) application:(UIApplication*)application 
continueUserActivity:(NSUserActivity*)userActivity 
  restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>>* _Nullable))restorationHandler 
{
    [AUAppDelegate.instance application:application 
                   continueUserActivity:userActivity 
                     restorationHandler:restorationHandler];

    return YES;
}
```

* Please remove the "Assets → Plugins → Airbridge → iOS → Delegate → AUAppController.mm" file once the above change has been made.

#### The issue with the app closing instantly upon launch on iOS

```html Text lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
Error loading /var/containers/Bundle/Application/…/Frameworks/UnityFramework.framework/UnityFramework (…)
: dlopen(/var/containers/Bundle/Application/…/Frameworks/UnityFramework.framework/UnityFramework, …)
: Library not loaded: @rpath/AirBridge.framework/AirBridge
```

If you are using Airbridge Unity SDK version 1.14.1 or 1.16.2, Please update to version 1.16.3.

#### The issue with no compatible version found for AirBridge on iOS

```html Text lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
[!] CocoaPods could not find compatible versions for pod "AirBridge":
    In Podfile:
        AirBridge (= {MISSING_VERSION})
```

If you can't find a compatible [AirBridge](https://cocoapods.org/pods/AirBridge) version on iOS, execute the command below to update the source repository.

```bash lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
pod repo update
pod install --repo-update
```

After updating your source repository, run the `pod search AirBrdige` command to verify that the correct AirBridge version exists in your repository, and then proceed with the iOS build.

## Sample App

[Unity Sample App](https://github.com/ab180/airbridge-unity-example)

## Migration Guide

Before updating the SDK, please review the following information.

#### 1.14.1

With support for the privacy manifest, the Static Library has been changed to a Dynamic Library.

If you are installing using EDM4U, click on \[Assets]>\[External Dependency Manager]>\[iOS Resolver]>\[Settings] at the top of Unity to proceed with iOS builds after unchecking the 'Link frameworks statically' checkbox in the Podfile Configurations section of the iOS Resolver Settings window displayed.

<link rel="alternate" hrefLang="en" href="https://help.airbridge.io/en/developers/deprecated-unity-sdk-v1" />

<link rel="alternate" hrefLang="ko" href="https://help.airbridge.io/ko/developers/deprecated-unity-sdk-v1" />
