Tenjin Unity 插件
- 允许 Unity 的开发商快速集成 Tenjin 的 install API。
- 查看 iOS 和 Android 文档,并将合适的平台设置应用于你的 builds。最重要的是:
iOS:
- 如果你使用 Unity iOS SDK v1.12.0 或更高版本,请使用 Xcode 12。
- 运行时,请确保以下框架已经自动加载到 Xcode build。 如果有缺失,请自行手动添加。
- AdServices.framework
- AdSupport.framework
- AppTrackingTransparency.framework
- iAd.framework
- StoreKit.framework
- 对于 AppTrackingTransparency 隐私授权,请确保更新你项目中
.plist
文件,并添加Privacy - Tracking Usage Description 隐私 - 追踪用途描述
(NSUserTrackingUsageDescription) 以及你希望展示的文字信息。该库仅适用于 iOS 14.0+ 。 - 对于 Apple Search Ads Attribution ASA 追踪 , 请确保将 SDK 更新至 v1.12.6+ ,并添加
AdServices.framework
库。该库仅适用于 iOS 14.3+
Android:
- 如果你已经集成的 SDK 中有安装 Google Play Services 或者使用 PlayServicesResolver, 则可能需要删除以下文件:
/Assets/Plugins/Android/play-services-ads-identifier--*.aar
/Assets/Plugins/Android/play-services-basement---*.aar
如果你使用 Unity 版本 2019.4.21f1 或以上,并且使用Gradle 来创建安卓应用, 你可能遇到以下错误如
DuplicateMethodException
等, 或者发现 referrer install 无法正常工作。如果遇到以上情况,请:- 请删除
Assets/Plugins/Android
文件夹下除tenjin.aar
的所有*.aar
文件. 将以下添加到你的
mainTemplate.gradle
文件:// Android Resolver Repos Start ([rootProject] + (rootProject.subprojects as List)).each { project -> project.repositories { def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/") maven { url "https://maven.google.com" } maven { url "https://s3.amazonaws.com/moat-sdk-builds" } maven { url 'https://developer.huawei.com/repo/' } mavenLocal() mavenCentral() google() } } // Android Resolver Repos End apply plugin: 'com.android.library' **APPLY_PLUGINS** dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) // Android Resolver Dependencies Start implementation 'com.android.support:multidex:1.0.3' implementation 'com.google.android.gms:play-services-analytics:{version}' implementation 'com.android.installreferrer:installreferrer:{version}' implementation 'com.huawei.hms:ads-identifier:{version}' implementation 'com.huawei.hms:ads-installreferrer:{version}' androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.2', { exclude group: 'com.android.support', module: 'support-annotations' }) // Android Resolver Dependencies End **DEPS**}
- Add the following entry to the
gradleTemplate.properties
file:android.useAndroidX=true
- Add the following entry to the
- 请删除
如果你在应用初始化时遇到以下错误, 请将 tenjin.aar 从
/Assets/Plugins/Android/Tenjin/libs
移到/Assets/Plugins/Android/
. 同时检查混淆设置 Proguard Settings[4].AndroidJavaException: java.lang.NoSuchMethodError: no static method with name='setWrapperVersion' AndroidJavaException: java.lang.ClassNotFoundException: com.tenjin.android.TenjinSDK
- 如果你将 Tenjin SDK 更新至 v1.12.9 或以上, 请使用 Unity 3D 2019.4.21f1 及以上版本。如果你使用较低 Unity 版本,请联系我们,我们可以帮你进行 SDK 定制。 同时, 请升级 External Dependency Manager for Unity 到 1.12.167.
有任何技术问题,请邮件至: support@tenjin.com
目录
- SDK Integration SDK 集成
- Google Play
- Amazon store
- OAID
- Proguard
- App Initilization 初始化
- App Store 应用商店
- ATTrackingManager (iOS)
- SKAdNetwork and Conversion Value
- SKAdNetwork iOS 15+ Postbacks
- GDPR
- Purchase Events 内购事件
- Custom Events 自定义事件
- Deferred Deeplinks 深度链接
- Server-to-server integration 服务器集成
- App Subversion AB 测试
- Impression Level Ad Revenue Integration 展示层级收益集成
- Testing
Tenjin 安装/会话(install/session)集成
下载最新版本 Unity SDK here.
将
TenjinUnityPackage.unitypackage
导入你的项目:Assets -> Import Package
.我们默认包含了 Google Play Services AAR 文件作为我们 SDK 的一部分。如果不需要,你可以进行删除:
/Assets/Plugins/Android/play-services-*.aar
/Assets/Plugins/Android/installreferrer-*.aar
我们有一个 demo project - tenjin-unity-demo, 以便让你更好地了解 Unity SDK 的集成。
Google Play
App Store 默认值为 unspecified。 如果你在谷歌应用商店推广,请将此值设为 googleplay。
将 App Store Type 值设为 googleplay
:
BaseTenjin instance = Tenjin.getInstance("<API_KEY>");
instance.SetAppStoreType(AppStoreType.googleplay);
Amazon store
App Store 默认值为 unspecified。 如果你在亚马逊应用商店推广,请将此值设为 amazon。
将 App Store Type 值设为 amazon
:
BaseTenjin instance = Tenjin.getInstance("<API_KEY>");
instance.SetAppStoreType(AppStoreType.amazon);
OAID 及其他安卓应用商店
Tenjin 支持使用 OAID 在其他非 Google Play 商店渠道进行推广。我们有以下用于集成 OAID 库的选项。
MSA OAID
集成 MSA 库, 在此下载 oaid_sdk_1.0.25.aar.
将 oaid_sdk_1.0.25.aar
文件置于你项目中安卓库路径下: /Assets/Plugins/Android
将 App Store Type 值设为 other
:
BaseTenjin instance = Tenjin.getInstance("<API_KEY>");
instance.SetAppStoreType(AppStoreType.other);
Huawei OAID
对于在华为海外应用商店的推广,你可以集成华为 OAID 库来获取 OAID。可将华为的 OAID 库,在项目中添加以下内容:Huawei AAR file: huawei-ads-identifier.aar. 如果你的应用在 Huawei App Gallery 华为海外应用商店 上架,请下载 Huawei Install Referrer 文件: huawei-ads-installreferrer.aar.
将华为文件置于你项目中安卓库路径下: /Assets/Plugins/Android
将 App Store Type 值设为 other
:
BaseTenjin instance = Tenjin.getInstance("<API_KEY>");
instance.SetAppStoreType(AppStoreType.other);
Proguard Settings 混淆设置
-keep class com.tenjin.** { *; }
-keep public class com.google.android.gms.ads.identifier.** { *; }
-keep public class com.google.android.gms.common.** { *; }
-keep public class com.android.installreferrer.** { *; }
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}
-keepattributes *Annotation*
如果你使用华为库,你可以使用下面设置:
-keep class com.huawei.hms.ads.** { *; }
-keep interface com.huawei.hms.ads.** { *; }
App Initialization 初始化
- 在 Tenjin 面板 获取
<API_KEY>
- 在项目的
Start()
和OnApplicationPause()
方法中加入BaseTenjin instance = Tenjin.getInstance("API_KEY")
和instance.Connect()
代码示例:
using UnityEngine;
using System.Collections;
public class TenjinExampleScript : MonoBehaviour {
// Use this for initialization
void Start () {
BaseTenjin instance = Tenjin.getInstance("API_KEY");
instance.Connect();
}
// Update is called once per frame
void Update () {
}
void OnApplicationPause(bool pauseStatus){
if (pauseStatus) {
//do nothing
}
else {
BaseTenjin instance = Tenjin.getInstance("API_KEY");
instance.Connect();
}
}
}
注意: 请确保在所有的 Start()
和 OnApplicationPause()
初始化 Tenjin, 而非仅初次应用打开。Tenjin 内部会定期审查客户 SDK 集成情况,如发现未按指引集成,我们可能会即时停用你的账户。
App Store 应用商店类型
我们支持以下应用商店选项,
- googleplay
- amazon
- other
默认情况下, 应用商店类型设置为 unspecified. 请根据自身应用推广情况设置相应的值。华为海外商店推广请设置为 other:
AndroidManifest.xml
:
<meta-data
android:name="TENJIN_APP_STORE"
android:value="{{SET_APP_STORE_TYPE_VALUE}}" />
SetAppStoreType()
:
BaseTenjin instance = Tenjin.getInstance("<API_KEY>");
instance.SetAppStoreType(AppStoreType.{{SET_APP_STORE_TYPE_VALUE}});
ATTrackingManager (iOS)
从 iOS 14 开始,你可以选择初始话并显示 ATTrackingManager 权限提示,让用户选择允许或不允许。如果用户选择不允许追踪,IDFA 的值将会是0,如果用户选择同意追踪, connect()
方法就会发送 IDFA 到我们的服务器。即便不使用 ATTrackingManager,你也可以调用 Tenjin connect()
, 目前 ATTrackingManager 弹窗尚未强制弹出,预计苹果会在2021年初强制推行。
using UnityEngine;
using System.Collections;
using UnityEngine.iOS;
public class TenjinExampleScript : MonoBehaviour {
void Start() {
TenjinConnect();
}
void OnApplicationPause(bool pauseStatus) {
if (!pauseStatus) {
TenjinConnect();
}
}
public void TenjinConnect() {
BaseTenjin instance = Tenjin.getInstance("API_KEY");
#if UNITY_IOS
if (new Version(Device.systemVersion).CompareTo(new Version("14.0")) >= 0) {
// Tenjin wrapper for requestTrackingAuthorization
instance.RequestTrackingAuthorizationWithCompletionHandler((status) => {
Debug.Log("===> App Tracking Transparency Authorization Status: " + status);
// Sends install/open event to Tenjin
instance.Connect();
});
}
else {
instance.Connect();
}
#elif UNITY_ANDROID
// Sends install/open event to Tenjin
instance.Connect();
#endif
}
}
展示 ATT 权限提示
要遵守 Apple 的 ATT 指南,您必须提供 ATT 权限提示的描述,然后在您的应用程序中实施权限请求。
注意:在您的游戏中投放广告之前,您必须执行权限请求。
设定用户跟踪描述
Apple 需要开发者描述 ATT 提示的用途。您需要在 Xcode 项目的 Info.plist
文件中使用 NSUserTrackingUsageDescription
设置描述。您必须提供一条消息,告知用户您为何请求使用设备跟踪数据的权限:
- 在您的 Xcode 项目导航器中,打开
Info.plist
文件。 - 单击属性列表编辑器中任意键旁边的添加按钮 (+) 以创建新的属性键。
- 输入键名
NSUserTrackingUsageDescription
。 - 选择字符串 String 值类型。
- 在值字段中输入应用跟踪透明度消息。一些例子包括:
- “我们将使用您的数据来提供更好的个性化广告体验。”
- “我们会尝试根据您使用的应用程序、您使用的设备以及您所在的国家/地区展示您最感兴趣的应用程序和产品的广告。”
- “我们会尝试根据您使用的应用为您最感兴趣的应用和产品展示广告。”
注意:Apple 提供了特定的应用商店指南,为所有面向最终用户的隐私相关功能定义了可接受的使用和消息传递。Tenjin 不提供法律意见。因此,此页面上的信息不能替代您寻求自己的法律顾问来确定您的业务和流程的法律要求以及如何解决这些要求。
SKAdNetwork and Conversion Values
作为 SKAdNetwork 的一部分,我们为 registerAppForAdNetworkAttribution()
和 updateConversionValue(_:)
创建的封装方案,可以注册等效的 SKAdNetwork 方案并同时发送 conversion values 到我们的服务器。
updateConversionValue(_:) 6位值来对应应用内事件,不能二进制形式输入,而应为 0-63 的整数。我们的服务器将拒绝任何无效值。
using UnityEngine;
using System.Collections;
public class TenjinExampleScript : MonoBehaviour {
void Start() {
TenjinConnect();
}
void OnApplicationPause(bool pauseStatus) {
if (!pauseStatus) {
TenjinConnect();
}
}
public void TenjinConnect() {
BaseTenjin instance = Tenjin.getInstance("API_KEY");
#if UNITY_IOS
// Registers SKAdNetwork app for attribution
instance.RegisterAppForAdNetworkAttribution();
// Sends install/open event to Tenjin
instance.Connect();
// Sets SKAdNetwork Conversion Value
// You will need to use a value between 0-63 for <YOUR 6 bit value>
instance.UpdateConversionValue(<your 6 bit value>);
#elif UNITY_ANDROID
// Sends install/open event to Tenjin
instance.Connect();
#endif
}
}
SKAdNetwork and iOS 15+ Advertiser Postbacks 广告主回调
需要将 Tenjin 指定为 SKAdNetwork 回调接收方,请进行以下操作:
- 在 Xcode 的项目导航器中选择
Info.plist
。 - 单击"属性/Property"列表编辑器中某个键旁边的添加按钮 (+),然后按回车键。
- 输入名称
NSAdvertisingAttributionReportEndpoint
。 - 从"类型/Type"列的弹出菜单中选择"String"。
- 输入
https://tenjin-skan.com
。
以上操作是为适配 Apple 的指引,具体详情可参考网址: https://developer.apple.com/documentation/storekit/skadnetwork/configuring_an_advertised_app.
注意:如果您使用 AppLovin MAX 作为聚合,他们的 Unity SDK 将在构建过程中使用他们自己的 URL 覆盖您为“NSAdvertisingAttributionReportEndpoint”输入的任何值。 在以下过程中被覆盖后,您应该可以在 XCode 中将 NSAdvertisingAttributionReportEndpoint 设置为“https://tenjin-skan.com”。
- 按照 Unity 此处 概述的步骤导出 iOS 应用程序。
2.构建iOS应用程序后,您应该有一个具有以下结构的XCode项目:https://docs.unity3d.com/Manual/StructureOfXcodeProject.html
- 导航到 XCode 项目中的
Info.plist
文件,手动将 NSAdvertisingAttributionReportEndpoint 更改为https://tenjin-skan.com
。 或者,您可以要求您的 AppLovin 客户经理设置将回发转发给 Tenjin。
GDPR
作为 GDPR 合规的一部分,使用 Tenjin 的 SDK,你可以选择加入和退出设备/用户,或选择要加入或退出的特定于设备的相关参数。OptOut()
不会向 Tenjin 发送任何 API 请求,我们也不会处理任何事件。
To opt-in/opt-out:
void Start () {
BaseTenjin instance = Tenjin.getInstance("API_KEY");
boolean userOptIn = CheckOptInValue();
if (userOptIn) {
instance.OptIn();
}
else {
instance.OptOut();
}
instance.Connect();
}
boolean CheckOptInValue(){
// check opt-in value
// return true; // if user opted-in
return false;
}
- 要选择加入/退出特定的设备相关参数,可以使用
OptInParams()
或OptOutParams()
。 OptInParams()
将仅发送指定的设备相关参数.OptOutParams()
将发送除指定参数外的所有与设备相关的参数。请注意,我们至少需要以下字段以保证归因正常运行。如果以下某一必需字段缺失,相关应用事件将不会被记录或者处理。
- For Android,
advertising_id
- For iOS
developer_device_id
- 如果你使用 IMEI 或 OAID, 请添加:
imei
oaid
- 如果你使用 Google Ads 投放,请添加以下字段:
platform
os_version
locale
device_model
build_id
- For Android,
如果只想使用 OptInParams()
获取与设备相关的特定参数,在下面的样例中, 我们只发送这些设备相关的参数: ip_address
, advertising_id
, developer_device_id
, limit_ad_tracking
, referrer
, 和 iad
:
BaseTenjin instance = Tenjin.getInstance("API_KEY");
List<string> optInParams = new List<string> {"ip_address", "advertising_id", "developer_device_id", "limit_ad_tracking", "referrer", "iad"};
instance.OptInParams(optInParams);
instance.Connect();
如果要使用 OptOutParams()
发送除特定设备相关参数以外的所有参数,如下样例中,我们会发送除了 locale
, timezone
, 和 build_id
之外的所有相关的参数。
BaseTenjin instance = Tenjin.getInstance("API_KEY");
List<string> optOutParams = new List<string> {"locale", "timezone", "build_id"};
instance.OptOutParams(optOutParams);
instance.Connect();
设备相关参数
参数 | 描述 | 平台 | 索引 |
---|---|---|---|
advertising_id | 设备 Advertising ID | All | Android), iOS |
developer_device_id | ID for Vendor | iOS | iOS |
limit_ad_tracking | 开启限制广告追踪 | All | Android), iOS |
platform | 平台 | All | iOS or Android |
referrer | Google Play Install Referrer | Android | Android |
iad | Apple Search Ad parameters | iOS | iOS |
os_version | 操作系统版本 | All | Android, iOS |
device | 设备名称 | All | Android, iOS (hw.machine) |
device_manufacturer | 设备制造商 | Android | Android |
device_model | 设备型号 | All | Android, iOS (hw.model) |
device_brand | 设备品牌 | Android | Android |
device_product | 设备产品 | Android | Android |
device_model_name | device machine | iOS | iOS (hw.model) |
device_cpu | 设备cpu名称 | iOS | iOS (hw.cputype) |
carrier | 运营商 | Android | Android) |
connection_type | 移动数据或 wifi | Android | Android) |
screen_width | 设备屏幕宽度 | Android | Android |
screen_height | 设备屏幕高度 | Android | Android |
os_version_release | 操作系统版本 | All | Android, iOS |
build_id | build ID | All | Android, iOS (kern.osversion) |
locale | 设备区域 | All | Android), iOS |
country | 区域国家 | All | Android), iOS |
timezone | 时区 | All | Android, iOS |
你可以通过 Live Test Device Data Tool.来验证集成是否正常运行。 添加 advertising_id
或者 IDFA/GAID
到测试设备列表中。你可以在 Support -> Test Devices找到内容。转到 SDK Live page 然后从 App 发送测试事件,你可以看到即时的数据如下:
内购事件
iOS 内购 IAP 验证
iOS 验证 receipt 需要 transactionId
和 receipt
(signature
将设置为 null
). 对与 receipt
,请确保从 unity 发送Payload
的receipt(以 base64 编码的 ASN.1 receipt)。
重要提示: 如果你有订阅内购(subscription IAP),你需要在, you will need to add your app's shared secret in the Tenjin dashboard添加你 App 的共享密钥(shared secret)。你的 iOS App-Specific Shared Secret 获取路径: iTunes Connect Console > Select your app > Features > In-App Purchases > App-Specific Shared Secret.
Android 内购验证 IAP Validation
Android 的 receipt 验证必须提供 receipt
和 signature
, (transactionId
设置为 to null
).
重要提示: 你需要在 Tenjin dashboard添加 App 的 public key。获取 Base64-encoded RSA public key 的路径为 Google Play Developer Console > Select your app > Development Tools > Services & APIs。
iOS 和 Android 示例:
public static void OnProcessPurchase(PurchaseEventArgs purchaseEventArgs) {
var price = purchaseEventArgs.purchasedProduct.metadata.localizedPrice;
double lPrice = decimal.ToDouble(price);
var currencyCode = purchaseEventArgs.purchasedProduct.metadata.isoCurrencyCode;
var wrapper = Json.Deserialize(purchaseEventArgs.purchasedProduct.receipt) as Dictionary<string, object>; // https://gist.github.com/darktable/1411710
if (null == wrapper) {
return;
}
var payload = (string)wrapper["Payload"]; // For Apple this will be the base64 encoded ASN.1 receipt
var productId = purchaseEventArgs.purchasedProduct.definition.id;
#if UNITY_ANDROID
var gpDetails = Json.Deserialize(payload) as Dictionary<string, object>;
var gpJson = (string)gpDetails["json"];
var gpSig = (string)gpDetails["signature"];
CompletedAndroidPurchase(productId, currencyCode, 1, lPrice, gpJson, gpSig);
#elif UNITY_IOS
var transactionId = purchaseEventArgs.purchasedProduct.transactionID;
CompletedIosPurchase(productId, currencyCode, 1, lPrice , transactionId, payload);
#endif
}
private static void CompletedAndroidPurchase(string ProductId, string CurrencyCode, int Quantity, double UnitPrice, string Receipt, string Signature)
{
BaseTenjin instance = Tenjin.getInstance("API_KEY");
instance.Transaction(ProductId, CurrencyCode, Quantity, UnitPrice, null, Receipt, Signature);
}
private static void CompletedIosPurchase(string ProductId, string CurrencyCode, int Quantity, double UnitPrice, string TransactionId, string Receipt)
{
BaseTenjin instance = Tenjin.getInstance("API_KEY");
instance.Transaction(ProductId, CurrencyCode, Quantity, UnitPrice, TransactionId, Receipt, null);
}
订阅内购 Subscription IAP
重要提示: 如果你有订阅内购,则需要在 Tenjin dashboard添加 App 的 public key。iOS 的 Shared Secret 获取路径为 iTunes Connect Console > Select your app > Features > In-App Purchases > App-Specific Shared Secret。
请注意,你有责任在每个订阅间隔内发送一次订阅交易(例如,对于每月订阅,你需要每月向我们发送1笔交易)。
在下面的示例时间轴中,交易事件仅应在“首次收费”和“续订”事件中发送。在试用期间,请勿将交易事件发送给 Tenjin。Tenjin不 会对重复交易进行重复数据删除。
有关订阅的更多信息,请参阅: Apple documentation on Working with Subscriptions
自定义事件集成
- 在 Unity project 中包含 Assets 文件夹
- 在自定义事件的 projects method 中为命名事件编写以下内容:
Tenjin.getInstance("<API_KEY>").SendEvent("name")
以及需为整数值的命名事件的以下内容:Tenjin.getInstance("<API_KEY>").SendEvent("nameWithValue","value")
- 确保传递的
value
为整数,如果不是整数,则无法被传递。
代码示例:
void MethodWithCustomEvent(){
//event with name
BaseTenjin instance = Tenjin.getInstance ("API_KEY");
instance.SendEvent("name");
//event with name and integer value
instance.SendEvent("nameWithValue", "value");
}
.SendEvent("name")
is for events that are static markers or milestones. This would include things like tutorial_complete
, registration
, or level_1
.
.SendEvent("name", "value")
is for events that you want to do math on a property of that event. For example, ("coins_purchased", "100")
will let you analyze a sum or average of the coins that have been purchased for that event.
Deferred Deeplinks 深度链接
如果你使用其他服务产生延迟的深度链接,你可以向 Tenjin 发送这个链接,来处理已经已经打开 Tenjin 归因的深度链接。
using UnityEngine;
using System.Collections;
public class TenjinExampleScript : MonoBehaviour {
// Use this for initialization
void Start () {
BaseTenjin instance = Tenjin.getInstance("API_KEY");
instance.Connect("your_deeplink://path?test=123");
}
}
Server-to-server integration 服务器集成
Tenjin 提供服务器到服务器集成,这是一项付费功能。 如果您想访问文档,请发送电子邮件至 support@tenjin.com 并讨论定价。
用于 A/B 测试的 App Subversion 参数 (需要使用 DataVault)
如果你想运行 A/B 测试和差异报告,我们可以使用 appendAppSubversion
方法将数字值附加到你的应用程序版本中。例如,如果你的应用程序版本 1.0.1
设置了 appendAppSubversion: @8888
,报告中将为1.0.1.8888
。
这些数据将在 DataVault 中,你可以通过 subversion 值来运行报告。
BaseTenjin instance = Tenjin.getInstance("<API KEY>");
instance.AppendAppSubversion(8888);
instance.Connect();
Impression Level Ad Revenue Integration 展示层级收益集成
展示层级收益数据为付费功能,如有需要请联系你的客户经理或者邮件至 support@tenjin.com 讨论合约事宜。
Tenjin 目前支持与以下聚合平台展示数据进行集成:
- AppLovin
- IronSource
集成测试
你可以通过我们的 Live Test Device Data Tool 来验证内购查看 SDK 集成是否正常。添加你测试设备的 advertising_id
或 IDFA/GAID
到测试设备名单中。你可以在面板上 DIAGNOSE -> Test Devices 查看。 点击到 SDK Live Data 页,并从 App 端发送事件,如果集成没有问题,你可以很快在面板上看到事件记录。