Airbridge Unity SDK 需要 Unity
2018.4
及以上版本。
注意
Airbridge Unity SDK 使用
unity-jar-resolver
(Unity 的外部依赖关系管理器,英文名为 External Dependency Manager for Unity,简称 EDM4U) 来管理库依赖性。如果使用 1.9.3 以下版本的 Airbridge Unity SDK,请事先在 此页 完成相应的 Unity 包设置。
对于 Airbridge Unity SDK 1.9.3 及以上版本,Airbridge Plugin 和 EDM4U 资产会自动导入,因此无需额外进行 Unity 包设置。
注意
如果使用 1.14.1 及以上版本的 Airbridge Unity SDK,请在 Unity 导航至 [Assets]>[External Dependency Manager]>[iOS Resolver]>[Settings]>[iOS Resolver Settings]>[Podfile Configurations],取消选中
Add use_frameworks! to Podfile
复选框,然后进行 iOS 构建。
请下载最新版本的 Airbridge Unity SDK。
请在 Unity 导航至 [Assets]>[Import Package]>[Custom Package...] 添加包。
包安装完成后可以在 Unity 查看 AB180
选项卡。
您可在 Unity 导航至 [AB180]>[Airbridge Settings] 查看以下页面:
注意
完成输入后,请点击
Update iOS App Setting
或Update Android Manifest
以应用设置内容。
注意
如需手动合并
Android Manifest
文件,请参照 [Project]>[Plugins]>[Airbridge]>[Android] 的AndroidManifest.xml
文件。
请在 Unity 的 [AB180]>[Airbridge Settings] 页面的 App Name
和 App Token
字段中输入在 Airbridge 注册的 App 名称(Unique ID)和 App SDK Token 信息。
App 名称(Unique ID)和 App SDK Token 可在 Airbridge 面板的 [设置]>[Token] 查看。
一般情况下,Airbridge Unity SDK 无需进行初始化操作,但在特殊情况下,可能需要针对各 OS 进行迁移操作。
完成 Airbridge SDK 安装和设置后,您可通过以下方法检查设置是否正确:
您可在 Unity 的 [AB180]>[Airbridge Settings]>[Log Level] 查看 App 的 Log。
您可在 Airbridge 面板的 [原始数据]>[App 实时记录] 查看 App 的 Log。
注意
Real-time Log 数据最长可能有 5 分钟的延迟。
请参阅以下指南在 Airbridge 面板进行深度链接设置:
请在 Unity 的 [AB180]>[Airbridge Settings] 的 Android URI Scheme
字段输入在 Airbridge 注册的 Android URI Scheme 信息。
Android URI Scheme 可在 Airbridge 面板的 [追踪链接]>[深度链接] 查看。
请在 Unity 的 [AB180]>[Airbridge Settings] 的 iOS URI Scheme
字段输入在 Airbridge 注册的 iOS URI Scheme 信息。
iOS URI Scheme 可在 Airbridge 面板的 [追踪链接]>[深度链接] 查看。
在 Airbridge 面板创建的追踪链接默认使用 deeplink.page
或 abr.ge
域名的追踪链接。您可通过以下步骤设置品牌域名,如 go.my_company.com/abcd
,为您的追踪链接添加品牌效果,从而提高 CTR。
请参照 本指南 设置品牌域名。
请在 Unity 的 [AB180]>[Airbridge Settings] 的 Custom Domain
字段输入在步骤 1. 设置的品牌域名。
为了收取用户点击的深度链接数据,请按如下所示注册收取 Message 的 Object 名称:
private void Awake()
{
AirbridgeUnity.SetDeeplinkCallback("AirbridgeManager");
}
如上所示完成 Callback
注册后,该 Class 将通过如下函数收取深度链接 URL:
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)
{
}
}
Airbridge Unity SDK 使用 Unity 提供的
UnitySendMessage
函数传递深度链接信息。
完成 Airbridge Unity SDK 深度链接设置后,可以通过点击 URI Scheme 检查是否能正确跳转到相应的 App 页面。
YOUR_APP_URI_SCHEME://
深度链接设置正确无误时,您可在 Airbridge 面板的 [原始数据]>[App 实时记录] 查看深度链接打开(Deeplink Open)记录。
Airbridge 收集以下用户标识符信息,以监测跨 Web 和 App 的用户贡献:
User Email : 用户邮箱
User Phone : 用户电话号码
User ID : 用户唯一 ID (可识别用户并且在 Web 端和 App 端一致的 ID)
User Alias : 可以代表用户的其他 ID (例:忠诚计划专用 ID、集团子公司统一 ID)
用户邮箱和电话号码将自动进行 SHA256 哈希处理后发送到服务器。
您可通过以下方法在 Airbridge Unity SDK 设置用户标识符信息:
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);
User Alias 最多可设置 10 个。
User Alias 的 key 是 string 类型,最多为 128 个字符。
User Alias 的 key 必须符合正则表达式 ^[a-z_][a-z0-9_]*$
User Alias 的 value 是 string 类型,最多为 128 个字符。
设置用户标识符信息后,所有事件将包含标识符信息进行发送。
您可以为提高 MTA(Multi-touch attribution, 多触点归因)分析的准确性、内部数据分析以及与第三方解决方案的集成等目的设置附加用户属性。
Dictionary<string, object> attrs = new Dictionary<string, object>();
AirbridgeUser user = new AirbridgeUser();
user.SetAttributes("key", "value");
AirbridgeUnity.SetUser(user);
User Attribute 最多可设置 100 个。
User Attribute 的 key 是 string 类型,最多为 128 个字符。
User Attribute 的 key 必须符合正则表达式 ^[a-z_][a-z0-9_]*$
User Attribute 的 value 类型可以为 integer、float、long、boolean 或 string,且如果是 string,则最多为 1024 个字符。
Airbridge Unity SDK 中设置的用户信息可在 Airbridge 面板的 [原始数据]>[App 实时记录] 查看。
您可在 SDK 中设置设备标识符,使以后收集的所有事件包含设备标识符。设置后,无论 App 是否关闭,设备标识符将保留,除非手动删除。
AirbridgeUnity.SetDeviceAlias("ADD_YOUR_KEY", "AND_YOUR_VALUE");
AirbridgeUnity.RemoveDeviceAlias("DELETE_THIS_KEY");
AirbridgeUnity.ClearDeviceAlias();
方法 | 说明 |
---|---|
SetDeviceAlias(string key, string value) | 将键值对添加到设备标识符中。 |
RemoveDeviceAlias(string key) | 删除相应于 key 的设备标识符。如果没有相应的设备标识符,则不执行任何操作。 |
ClearDeviceAlias() | 删除所有设备标识符。 |
Airbridge Unity SDK 调用的所有事件都可以包含以下 6 个属性进行发送:
Event Category:事件名称 (string) 必填
Event Action:事件属性 1 (string)
Event Label:事件属性 2 (string)
Event Value:事件属性 3 (double)
Event Semantic Attributes:标准事件属性 (dictionary<string, object>)
Event Custom Attributes:自定义事件属性 (dictionary<string, object>)
为方便起见,Airbridge Unity SDK 提供以下 3 种用户事件:
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);
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);
AirbridgeEvent @event = new AirbridgeEvent(Airbridge.Constants.CATEGORY.SIGN_OUT);
AirbridgeUnity.TrackEvent(@event);
AirbridgeUnity.ExpireUser();
为方便起见,Airbridge Unity SDK 提供以下产品 Class 和电商事件:
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_HOME);
AirbridgeUnity.TrackEvent(@event);
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);
AirbridgeUnity.TrackEvent(@event);
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);
AirbridgeUnity.TrackEvent(@event);
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);
AirbridgeUnity.TrackEvent(@event);
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);
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);
在 Airbridge Unity SDK 中,您可通过以下方法发送自定义事件:
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);
如需直接配置并发送 Semantic Attribute,请参阅 本指南。
Airbridge Unity SDK 发送的事件可在 Airbridge 面板的 [原始数据]>[App 实时记录] 查看。
您可在 Unity 的 [AB180]>[Airbridge Settings] 设置 SDK Signature Secret
字段和 SDK Signature Secret ID
字段,以防止 SDK 伪造(SDK Spoofing)。
为了设置 SDK 签名,需要 SDK Signature Secret 和 SDK Signature Secret ID。请参阅 本指南 获取这 2个值。
如果出于内部数据分析等目的需要发送未经哈希处理的用户标识符信息,您可在 Unity 的 [AB180]>[Airbridge Settings] 设置 User Info Hash Enabled
字段,以停止对 User Email 和 User Phone 信息的哈希处理。
注意
由于此选项将敏感个人信息提供给第三方,因此必须事先采取额外的内部安全措施。
您可在 Unity 的 [AB180]>[Airbridge Settings] 设置 Session Timeout Seconds
字段,以在设定的会话期间内,即使用户重新启用 App,也可判断为同一个会话,而不重新发送 App 启用事件。
此功能在根据隐私法(例:GDPR、CCPA)收集和传输数据时需要征得用户同意的情况下非常有用。
您可在 Unity 的 [AB180]>[Airbridge Settings] 设置 Auto Start Tracking Enabled
字段,以明确地开始收集和传输数据。
如果关闭此功能,则需要明确调用以下函数才能正确进行数据收集:
AirbridgeUnity.StartTracking();
如果由于 App 内的多个深度链接操作,导致难以通过 Airbridge 一目了然地查看再互动(Re-engagement)绩效,您可在 Unity 的 [AB180]>[Airbridge Settings] 设置 Track Airbridge Link Only
字段,以过滤并仅查看由 Airbridge 深度链接产生的绩效。
开启此功能后,仅当通过符合以下条件的深度链接打开 App 时,才会监测深度链接绩效。
通过 Airbridge 面板中注册的深度链接打开 App 时
通过 airbridge.io
深度链接打开 App 时
通过 deeplink.page
深度链接打开 App 时
当 airbridge_referrer
query 信息存在时
您可在 Unity 的 [AB180]>[Airbridge Settings] 设置 Location Collection Enabled
字段,以收集用户的位置信息。
注意
位置信息必须以合法目的和方式收集,使用此功能请谨慎。
此功能仅在 Android 上可用,且 AndroidManifest.xml
中必须包含以下权限设置:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
您可在 Unity 的 [AB180]>[Airbridge Settings] 设置 Facebook Deferred App Link Enabled
字段,以通过 Airbridge Unity SDK 收取 Facebook 的 Deferred App Link。
注意
如需使用此功能,必须事先完成 Facebook SDK 设置。请参阅 此页。
根据 Apple 政策,iOS 只有在 ATT (App Tracking Transparency, 应用跟踪透明度)征得用户同意,才能收集 IDFA 信息。
您可在 Unity 的 [AB180]>[Airbridge Settings] 设置 iOS Tracking Authorize Timeout Seconds
字段,以延迟安装事件,使安装事件包含 IDFA。
根据 Apple 政策,在 iOS 14.5 及以上版本中,为了收集 IDFA,必须提供 AppTrackingTransparency
弹出窗口。只能收集在 AppTrackingTransparency
弹出窗口中表示同意使用个人信息的用户的 IDFA。
void Start() {
AppTrackingTransparency.RequestTrackingAuthorization();
}
您还可以参阅 Unity 指南 提供 ATT 弹出窗口。请仅使用两种方法之一。
App 卸载追踪设置在 Airbridge Unity SDK 1.9.0 及以上版本可用。
1. Firebase Cloud Messaging 设置
请参照 Firebase Cloud Messaging 文档 完成 App 的基本设置。
2. Firebase Push Token 发送
请参照以下指南发送通过 Firebase Cloud Messaging 设置生成的 Push Token:
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;
...
}
1. Apple Push Notification service 设置
请参照 Unity Mobile Notifications package 文档 完成该包的安装。
2. Device Token 发送
请参照以下指南发送 APNs Device Token:
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
仅通过安装 Web SDK 无法追踪 App 安装、App 启用、深度链接调用等额外事件。您可通过以下设置在 Hybrid App 调用应用内事件:
AirbridgeWebInterface webInterface;
webInterface = AirbridgeUnity.CreateWebInterface(
"YOUR_WEB_TOKEN", // web token
(msg) => $@"..." // post command function
);
您可通过 AirbridgeUnity.CreateWebInterface
控制 Web Interface。请参阅 Unity Hybrid App 集成指南。
注意
Hybrid App 设置在 Airbridge Unity SDK 1.9.3 及以上版本可用。
Android Airbridge Unity SDK 通过 Content Provider 进行自动初始化。因此,为了正常进行初始化,必须在 Project
> Plugins
> Android
> AndroidManifest.xml
文件中正确指定以下 Xml Tag
:
<provider
android:authorities="${applicationId}.co.ab180.airbridge.unity.AirbridgeContentProvider"
android:name="co.ab180.airbridge.unity.AirbridgeContentProvider"
android:exported="false" />
Android Airbridge Unity SDK 使用 Custom Activity 调用深度链接。如果用户已经在使用 Custom Activity,请在该 Custom Activity 中添加以下代码:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
@Override
protected void onResume() {
super.onResume();
AirbridgeUnity.processDeeplinkData(getIntent());
}
Android Airbridge Unity SDK 提供的 Android Manifest Merger 组件简单合并 Project
> Plugins
> Android
> AndroidManifest.xml
和 Project
> Plugins
> Airbridge
> Android
> AndroidManifest.xml
。因此,在满足所有特定需求并输出所需格式方面存在局限性。在特殊情况下,需要手动合并 AndroidManifest.xml
。
Android 11 版本添加的 Package Visibility 政策要求 App 通过 manifest
文件中的 <queries>
告知与其他 App 交互的包(package)。
Android Airbridge Unity SDK 符合此政策,并要求使用 5.6.4 及以上版本的 Gradle
和 3.6.0 及以上版本的 Android Gradle Plugin
以支持 <queries>
标签。
您可通过 此页 查看不同 Unity 版本所包含的 Gradle 版本。
如果您使用的 Gradle 版本低于 5.6.4
或 Android Gradle Plugin 版本低于 3.6.0
,可以通过以下设置使用特定 Unity 版本。
以下版本已包含 Gradle 5.6.4 及以上
版本以及 Android Gradle Plugin 3.6.0 及以上
版本,因此无需进行额外操作。
以下自定义选项仅在
Unity 2019.3 patch 7 及以上
版本可用。
1. 请从 Gradle Build Tool 下载 5.6.4 及以上版本的 Gradle
。
2. 请在 [Preferences]>[External Tools] 中,取消选中 Gradle Installed with Unity (recommended)
选项,然后将下载的 Gradle
文件路径设置为如下所示:
3. 请在 [Project Settings]>[Player]>[Android tab]>[Publishing Settings]>[Build] 中,同时选中以下选项:
Custom Main Gradle Template
Custom Launcher Gradle Template
4. 请对 2 个自动生成的文件都进行如下更改:
Assets/Plugins/Android/mainTemplate.gradle
Assets/Plugins/Android/launcherTemplate.gradle
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'
}
}
}
1. 请从 Gradle Build Tool 下载 5.6.4 及以上版本的 Gradle
。
2. 请在 [Preferences]>[External Tools] 中,取消选中 Gradle Installed with Unity (recommended)
选项,然后将下载的 Gradle
文件路径设置为如下所示:
3. 请在 [Project Settings]>[Player]>[Android tab]>[Publishing Settings]>[Build] 中,选中 Custom Gradle Template
选项,如下所示:
4. 请对生成的 Assets/Plugins/Android/mainTemplate.gradle
文件进行如下更改:
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'
}
}
以下自定义选项仅在
Unity 2018.4 patch 24 及以上
版本可用。
1. 请从 Gradle Build Tool 下载 5.6.4 及以上版本的 Gradle
。
2. 请在 [Build Settings]>[Android] 的 [Build System] 选中 Gradle
选项,如下所示:
3. 请在 [Preferences]>[External Tools] 中,取消选中 Gradle Installed with Unity (recommended)
选项,然后将下载的 Gradle
文件路径设置为如下所示:
4. 请在 [Project Settings]>[Player]>[Android tab]>[Publishing Settings]>[Build] 中,选中 Custom Gradle Template
选项,如下所示:
5. 请对生成的 Assets/Plugins/Android/mainTemplate.gradle
文件进行如下更改:
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'
}
}
Unity 2018.3 及以下版本不支持 Gradle 自定义选项。
iOS Airbridge Unity SDK 使用 Unity 提供的 IMPL_APP_CONTROLLER_SUBCLASS
创建 Custom AppController
。如果您已经在使用 IMPL_APP_CONTROLLER_SUBCLASS
实现了 Custom AppController
,请将以下代码添加到您的 Custom AppController
中:
- (BOOL) application:(UIApplication*)application
continueUserActivity:(NSUserActivity*)userActivity
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>>* _Nullable))restorationHandler
{
[AUAppDelegate.instance application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
return YES;
}
完成以上操作后,请删除原有的 Assets
> Plugins
> Airbridge
> iOS
> Delegate
> AUAppController.mm
文件。
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
随着支持 iOS Privacy Manifest,iOS Airbridge Unity SDK 1.14.1 及以上版本的静态库已更改为动态库。如果使用 EDM4U 进行安装,请在 Unity 的 [Assets]>[External Dependency Manager]>[iOS Resolver]>[Settings]>[iOS Resolver Settings]>[Podfile Configurations] 取消选中 Add use_frameworks! to Podfile
复选框,然后进行 iOS 构建。
更新 SDK 时,请考虑以下内容:
随着支持 iOS Privacy Manifest,静态库已更改为动态库。如果使用 EDM4U 进行安装,请在 Unity 的 [Assets]>[External Dependency Manager]>[iOS Resolver]>[Settings]>[iOS Resolver Settings]>[Podfile Configurations] 取消选中 Add use_frameworks! to Podfile
复选框,然后进行 iOS 构建。
解决了在 1.12.2 版本中存在的深度链接回调提供的深度链接 URL 被解码 2 次的问题。
深度链接回调提供的深度链接 URL 中不再添加 airbridge_referrer
。
1. 更新 iOS App 时,SKAN 转化值将以最后计算的值为准,不会进行额外计算。
1.12.0 以下版本计算 SKAN 转化值的时间最多为 24 小时。
对于新安装,这不会成为问题。
2. deeplink.page
已被弃用。从 1.12.0 开始,建议使用 abr.ge
作为深度链接域名。
为保持向后兼容,deeplink.page
仍然受支持并且正常工作。
3. trackingAuthorizeTimeout
的默认值更改为 30 秒。
Was this page helpful?
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);
Dictionary<string, object> attrs = new Dictionary<string, object>();
AirbridgeUser user = new AirbridgeUser();
user.SetAttributes("key", "value");
AirbridgeUnity.SetUser(user);
AirbridgeUnity.SetDeviceAlias("ADD_YOUR_KEY", "AND_YOUR_VALUE");
AirbridgeUnity.RemoveDeviceAlias("DELETE_THIS_KEY");
AirbridgeUnity.ClearDeviceAlias();
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);
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);
AirbridgeEvent @event = new AirbridgeEvent(Airbridge.Constants.CATEGORY.SIGN_OUT);
AirbridgeUnity.TrackEvent(@event);
AirbridgeUnity.ExpireUser();
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_HOME);
AirbridgeUnity.TrackEvent(@event);
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);
AirbridgeUnity.TrackEvent(@event);
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);
AirbridgeUnity.TrackEvent(@event);
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);
AirbridgeUnity.TrackEvent(@event);
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);
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);
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);
AirbridgeUnity.StartTracking();
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
void Start() {
AppTrackingTransparency.RequestTrackingAuthorization();
}
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;
...
}
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
AirbridgeWebInterface webInterface;
webInterface = AirbridgeUnity.CreateWebInterface(
"YOUR_WEB_TOKEN", // web token
(msg) => $@"..." // post command function
);
<provider
android:authorities="${applicationId}.co.ab180.airbridge.unity.AirbridgeContentProvider"
android:name="co.ab180.airbridge.unity.AirbridgeContentProvider"
android:exported="false" />
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
@Override
protected void onResume() {
super.onResume();
AirbridgeUnity.processDeeplinkData(getIntent());
}
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'
}
}
}
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'
}
}
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'
}
}
- (BOOL) application:(UIApplication*)application
continueUserActivity:(NSUserActivity*)userActivity
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>>* _Nullable))restorationHandler
{
[AUAppDelegate.instance application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
return YES;
}
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