Singular SDK 可作为 Flutter 的插件使用。以下说明将向您介绍如何将 Singular 集成到您的 Flutter 应用程序中。
前提条件
- 本文假设您有一个功能完善的 Flutter 应用程序。
- 要初始化 SDK,您需要 Singular SDK Key 和 SDK Secret。您可以在 Singular 平台的"开发工具 > SDK 集成 > SDK 密钥"中获取它们。
新功能:视频指南
观看视频,详细了解集成过程。我们建议同时使用视频和下面的书面指南。
集成 Singular 插件
要在 Flutter 应用程序中添加 Singular 插件,请在pubspec.yaml文件中添加以下几行:
dependencies:
singular_flutter_sdk: ^1.4.1
然后在终端导航到您的项目并运行以下程序:
flutter packages get
Android 附加步骤
添加依赖关系
对于 Android 应用程序,您需要在app/build.gradle 的依赖关系列表中添加 Singular 库,如下所示:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
//...
}
Singular SDK 需要 Google 移动广告 API,它是 Google Play 服务 API 17.0.0+ 的一部分。如果您已经在应用程序中集成了 Google Play 服务,则已满足要求。如果尚未集成,可以在应用程序的build.gradle 中加入以下依赖项,单独集成 Google Mobile Ads:
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
如果您已禁用 Singular SDK 的传递依赖关系,请在应用程序的build.gradle 中添加以下内容。
implementation 'com.android.installreferrer:installreferrer:2.2'
implementation 'com.google.android.gms:play-services-appset:16.0.2'
此外,如果您的应用程序通过三星 Galaxy Store 发布,请添加以下内容以支持三星 Galaxy Store 的安装引用程序:
implementation 'store.galaxy.samsung.installreferrer:samsung_galaxystore_install_referrer:4.0.0'
注: 如果在构建时出现DuplicateClasses(重复类 )错误,则可能已经有了 Google play-services,可以注释掉该依赖关系。
添加权限
在AndroidManifest.xml文件的<manifest>标记下添加这些权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="BIND_GET_INSTALL_REFERRER_SERVICE" />
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
此外,如果您的应用程序是通过 Samsung Galaxy Store 发布的,并且针对 Android 11 或更高版本,请添加以下内容以支持 Samsung Galaxy Store 的安装引用程序:
<queries>
<package android:name="com.sec.android.app.samsungapps" />
</queries>
如果您的应用程序构建针对 Android 12/API level 31 或更高版本,请添加访问 Google Advertising ID 的权限:
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
注意:如果您集成了儿童 SDK,请勿添加此权限。
iOS 的其他步骤
要使用 Singular 插件,必须添加 AdServices 框架。
初始化 Singular SDK
每次打开应用程序时,都应调用 Singular SDK 初始化代码。这是所有 Singular 归因功能的前提条件,它还会向 Singular 发送一个新的用户会话(会话用于计算用户留存)。
初始化代码位于应用程序的主窗口部件(即 main.dart)中,也就是应用程序打开时加载的第一个窗口部件。该部件必须是有状态的,代码必须添加到部件的initState()方法中。
- 首先,你必须创建一个 SingularConfig 对象。该对象包含你的 Singular SDK 密钥和秘密。
- 您还可以选择添加设置,以启用各种 SDK 功能。请参阅完整的选项列表。
- META 安装推荐人归属支持
启用"元安装推荐人 "属性所需的 SDK 配置:
- 在奇异配置对象中提供您的Facebook 应用程序 ID。
// To enable META Install Referrer config.facebookAppId = "INSERT YOUR FACEBOOK APP ID HERE";
- 在奇异配置对象中提供您的Facebook 应用程序 ID。
示例:
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_config.dart';
//...
class MyHomePage extends StatefulWidget {
//...
}
class _MyHomePageState extends State<MyHomePage> {
//...
@override
void initState() {
super.initState();
//...
SingularConfig config = new SingularConfig('SDK KEY', 'SDK SECRET');
// Set hashed User ID if available
config.customUserId = "b642b4217b34b1e8d3bd915fc65c4452";
// For iOS (Remove this if you are not displaying an ATT prompt)!
config.waitForTrackingAuthorizationWithTimeoutInterval = 300;
// To enable SkAdNetwork Support
config.skAdNetworkEnabled = true;
// To enable META Install Referrer
config.facebookAppId = "INSERT YOUR FACEBOOK APP ID HERE";
// (optional) Using Singular Global Properties feature to capture
// third party identifiers. The respective SDK(s) must be initialized
// before the Singular SDK. Example of passing the CleverTapID.
// var cleverTapId = CleverTapPlugin.getCleverTapID();
// config.withGlobalProperty("CLEVERTAPID", cleverTapId, true);
Singular.start(config);
}
处理 ATT 同意(设置初始化延迟)
显示 ATT(应用程序跟踪透明度)提示
从 iOS 14.5 开始,应用程序在访问和共享某些有助于追踪目的的用户数据(包括设备的IDFA)之前,必须征得用户同意(使用应用程序追踪透明度框架)。
拥有 IDFA 可以识别设备并执行安装归因,Singular 从中获益匪浅(不过也有不使用 IDFA 也能执行归因的方法)。我们强烈建议您征得用户同意获取 IDFA。
延迟初始化以等待 ATT 响应
默认情况下,Singular SDK 会在初始化时发送用户会话。当会话从新设备发送时,会立即触发 Singular 的归因流程--该流程仅根据 Singular 当时可用的数据执行。因此,在Singular SDK 发送第一个会话之前,必须征求同意并检索 IDFA。
要延迟启动用户会话,可在配置对象中使用waitForTrackingAuthorizationWithTimeoutInterval 选项初始化 Singular SDK。该选项已包含在上述代码示例中。
使用 Flutter 时,您需要依赖第三方软件包来实现应用程序跟踪透明度。例如:Flutter 的app_tracking_transparency插件。
提示:设置初始化延迟后,应用程序流程如下:
- 应用程序打开时,Singular SDK 会开始记录会话和用户事件,但不会将其发送到 Singular 服务器。
- 当应用程序跟踪透明度同意被授予/拒绝,或设定的时间过去后,SDK 会将会话和任何排队的事件发送到 Singular 服务器(有或没有 IDFA)。
- 然后,Singular 会利用 IDFA(如果有的话)启动归属过程。
下表总结了使用此集成的可能方案:
方案 | IDFA 可用性 |
用户看到同意对话框,并在设定时间结束前授予同意。 | IDFA 可用 |
用户看到同意对话框,并在设定时间结束前拒绝同意。 | IDFA 不可用 |
设定时间结束后,用户看到同意对话框并同意。 | IDFA 仅对同意后报告的用户事件有效 |
设置的时间已过,然后用户将看到同意对话框并拒绝同意。 | IDFA 不可用 |
用户看到同意对话框,未采取任何操作就退出了应用程序,然后在设定时间到期后打开应用程序并同意。 | 重新打开应用程序时,任何排队的事件都会发送到 Singular 服务器。IDFA 不能用于这些事件。同意后跟踪的任何事件都会有与之相关的 IDFA。 |
用户看到同意对话框后,未采取任何行动就退出了应用程序,随后打开应用程序并拒绝同意。 | 重新打开应用程序时,任何排队的事件都会发送到 Singular 服务器。IDFA 不能用于这些事件或之后跟踪的任何事件。 |
向 Singular 发送用户 ID(可选)
您可以使用 Singular SDK 方法向 Singular 发送内部用户 ID。
注:如果使用Singular 的跨设备解决方案,则必须在所有平台上收集用户 ID。
- 用户 ID 可以是任何标识符,但不应暴露 PII(个人身份信息)。例如,不应使用用户的电子邮件地址、用户名或电话号码。Singular 建议使用仅对第一方数据唯一的哈希值。
- 传递给Singular的用户ID值也应该是你在所有平台(Web/移动/PC/控制台/离线)上获取的相同的内部用户ID。
- Singular 将在用户级导出、ETL 和内部 BI 回传(如果配置)中包含用户 ID。用户 ID 是第一方数据,Singular 不会与其他方共享。
- 使用 Singular SDK 方法设置的用户 ID 值将一直存在,直到使用unsetCustomUserId 方法取消设置或卸载应用程序为止。关闭或重启应用程序不会取消设置用户 ID。
要设置用户 ID,请使用setCustomUserId 方法。要取消设置(例如,如果用户 "注销 "账户),请致电unsetCustomUserId 。
注意:如果多个用户使用一台设备,我们建议实施注销流程,为每次登录和注销设置和取消设置用户 ID。
如果已经知道应用程序打开时的用户 ID,请在初始化 Singular SDK 之前调用setCustomUserId 。这样,Singular 就能从第一次会话中获得用户 ID。不过,在用户注册或登录之前,用户 ID 通常是不可用的。在这种情况下,请在注册流程完成后调用setCustomUserId 。
Singular.setCustomUserID 方法 | |
---|---|
说明 | 向 Singular 发送用户 ID。 |
签名 | static void setCustomUserId(String customUserId) |
使用示例 |
|
Singular.unsetCustomUserID 方法 | |
说明 | 取消设置已发送至 Singular 的用户 ID。 |
签名 | static void unsetCustomUserId() |
使用示例 |
|
重要:此高级企业功能仅在特殊情况下可用。实施前请咨询 Singular 解决方案工程师。
Singular 可以通过服务器到服务器集成接收额外的移动事件跟踪数据。要使用此功能,必须将用户 ID 映射到 Singular 的移动设备跟踪标识符。
注意:在初始化Singular SDK后或获得用户ID后,请尽快调用此方法。
Singular.setDeviceCustomUserId方法 | |
---|---|
说明 | 设置与登录相同的自定义用户 ID,并将其映射到 Singular 的跟踪标识符。 |
签名 | static void setDeviceCustomUserId(String customUserId) |
使用示例 |
|
实现深度链接
深度链接是在用户手机上打开应用程序并直接将用户发送到特定页面或用户体验的链接,而不仅仅是应用程序的主窗口小部件。深度链接通常用于重定向营销活动,目标用户是手机中已经安装了应用程序但可能有一段时间没有使用的用户。Singular 支持通过 Singular Links 进行深度链接。
启用奇异链接
要在 iOS 和 Android 中启用 Singular Links,请参阅Singular Links Prerequisites。
要支持 Android,请在项目的MainActivity.java文件中添加以下代码:
import com.singular.flutter_sdk.SingularBridge;
import android.content.Intent;
@Override
protected void onNewIntent(@NonNull Intent intent) {
super.onNewIntent(intent);
SingularBridge.onNewIntent(intent);
}
import com.singular.flutter_sdk.SingularBridge;
import android.content.Intent;
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
SingularBridge.onNewIntent(intent);
}
对于iOS 支持,在项目的 AppDelegate.m 中添加以下内容:
// Top of AppDelegate.m
#import "SingularAppDelegate.h"
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
[SingularAppDelegate shared].launchOptions = launchOptions;
return [super application:application
didFinishLaunchingWithOptions:launchOptions];
}
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>>
*restorableObjects))restorationHandler {
[[SingularAppDelegate shared] continueUserActivity:userActivity
restorationHandler:restorationHandler];
return [super application:application continueUserActivity:userActivity
restorationHandler:restorationHandler ];
}
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
[[SingularAppDelegate shared] handleOpenUrl:url options:options];
return [super application:app openURL:url options: options];
}
import singular_flutter_sdk
override func application(_ application: UIApplication,
didFinishLaunchingWithOptions
launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
GeneratedPluginRegistrant.register(with: self) if
let singularAppDelegate = SingularAppDelegate.shared() {
singularAppDelegate.launchOptions = launchOptions
}
return super.application(application, didFinishLaunchingWithOptions:launchOptions)
}
override func application(_ application: UIApplication,
continue userActivity:NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?)-> Void) -> Bool {
if let singularAppDelegate = SingularAppDelegate.shared() {
singularAppDelegate.continueUserActivity(userActivity, restorationHandler:nil)
}
return super.application(application, continue:userActivity,
restorationHandler: restorationHandler);
}
override func application(_ app: UIApplication,
open url: URL, options:[UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if let singularAppDelegate = SingularAppDelegate.shared() {
singularAppDelegate.handleOpen(url, options: options)
}
return super.application(app, open: url, options: options);
}
处理 Singular 链接
使用 Singular 的处理机制来读取导致应用程序被打开的跟踪链接的详细信息。
例如
SingularConfig config = new SingularConfig('<SDK KEY>', '<SDK SECRET>');
config.singularLinksHandler = (SingularLinkParams params) {
String deeplink = params.deeplink;
String passthrough = params.passthrough;
bool isDeferred = params.isDeferred;
// Add your code here to handle the deep link
};
Singular.init(config);
跟踪事件(非收入)
Singular 可以收集有关应用程序内事件的数据,帮助分析营销活动的绩效并衡量关键绩效指标。例如,您的企业可能希望收集有关用户登录、注册、教程完成或游戏应用中等级提升的数据。
Singular 支持各种 标准事件。广告网络通常支持这些常用事件,以便进行报告和优化。另一个优点是,当你使用标准事件名称时,Singular 会自动识别并将其添加到事件列表中,而无需手动定义。我们建议尽可能使用标准事件。
发送到 Singular 的事件列表(附带属性)应由用户体验/营销/业务团队根据企业的营销关键绩效指标编制。业务团队可参考《如何跟踪应用内事件》指南:单一归因客户指南》。
您跟踪的每个事件都可以传递各种属性。请参阅推荐的每个事件的标准属性。
在代码中,使用 event 或 eventWithArgs 方法向 Singular 发送事件。
注:对于标准事件,请使用Flutter SDK 标准事件和属性列表中显示的事件 Flutter 名称,如 sngLogin。
对于自定义事件,即贵组织希望测量的事件,如果与 Singular 的任何标准事件不匹配,可使用任何自定义名称(最多 32 个字符)。我们建议使用英文名称,以便与可能从 Singular 接收事件以进行优化的广告网络合作伙伴兼容。
例如
Singular.event(Events.sngLogin);
Singular.eventWithArgs(eventName, {attributeName:attributeValue});
Map<String, Object> map = HashMap<String, Object>();
map ['name'] = 'John Doe';
map ['age'] = 30;
map ['isStudent'] = false;
Singular.eventWithArgs('event_Name', map);
跟踪收入
发送 IAP 事件
要让 Singular 跟踪应用程序的收入情况,请向 Singular 发送 IAP 事件。通过发送 IAP 事件,您还可以让 Singular 检查事件验证数据,确保它不是欺诈性的。
请参阅以下示例。
注:此代码片段需要 Flutter IAP 软件包,请访问https://pub.dev/packages/in_app_purchase。
import 'package:singular_flutter_sdk/singular_iap.dart';
import 'dart:io' show Platform;
if (Platform.isIOS) {
singularPurchase = new SingularIOSIAP(
product.rawPrice.toStringAsFixed(2),
product.currencyCode,
purchase.productID,
purchase.purchaseID,
purchase.verificationData.serverVerificationData
);
}
else if (Platform.isAndroid) {
singularPurchase = new SingularAndroidIAP(
product.rawPrice.toStringAsFixed(2),
product.currencyCode,
purchase.verificationData.serverVerificationData,
purchase.verificationData.localVerificationData
);
}
Singular.inAppPurchase(eventName, singularPurchase);
注:传递货币为三个字母的 ISO 4217 货币代码,如 "USD"、"EUR"、"INR"。
替代方法:发送自定义收入事件
Singular 也提供报告收入的选项,只需发送带有名称和收入金额的自定义收入事件即可。请注意,这种方法不会与 Singular 共享购买收据,因此无法让 Singular 验证这是一个合法的事件。
例如
Singular.customRevenue("MyCustomRevenue", "USD", 5.50);
Map<String, Object> map = HashMap<String, Object>();
map ['name'] = 'John Doe';
map ['age'] = 30;
map ['isStudent'] =false;
Singular.customRevenueWithAttributes('MyCustomRevenue','USD', 20, map);
注意:以三个字母的 ISO 4217 货币代码传递货币,如 "USD"、"EUR"、"INR"。
混合事件跟踪(高级)
Singular 建议通过集成到应用程序中的 Singular SDK 发送所有事件和收入。但是,Singular 也可以从其他来源收集事件和收入。
任何未从 Singular SDK 发送的事件都必须符合 Singular 的服务器到服务器事件文档要求,并提供匹配的设备标识符,以便正确归属事件。
重要:
如果服务器到服务器事件请求中使用的设备标识符在 Singular 中没有匹配的设备标识符,就会出现差异。请注意以下可能性:
- 如果事件请求是在Singular SDK 从应用程序会话记录设备标识符之前收到的,那么该事件请求将被视为未知设备的 "第一次会话",Singular 将把该设备作为有机归属。
- 如果 Singular SDK 确实记录了设备标识符,但 Singular SDK 标识符与服务器到服务器事件请求中指定的设备标识符不同,那么事件将被错误归属。
混合事件跟踪指南
Singular可以收集来自服务器的收入数据,帮助分析营销活动的表现和投资回报率。
要求:
- 从应用内注册或登录事件中捕获并传递设备标识符,并将此数据与服务器上的用户 ID 一起存储。由于用户的设备标识符可能会发生变化,因此请确保在用户生成应用程序会话时更新标识符。这将确保服务器端事件归属于正确的设备。
- 服务器端事件是平台特定的,只能使用与设备平台相匹配的设备标识符发送(如 iOS 设备的 IDFA 或 IDFV)。
- 您可以使用 Singular 内部 BI 回传机制将事件实时推送到内部端点,以便更新服务器端的数据集。请参阅内部 BI 回传常见问题。
- 查看服务器到服务器集成指南中的"跟踪收入 "部分,了解详情。
请点击以下链接了解如何启用这些合作伙伴。
添加广告收入归属支持
Singular与谷歌AdMob、AppLovin、Unity LevelPlay(IronSource)和TradPlus等中介平台集成,用于广告收入归属。通过我们的通用广告收入 SDK 集成,Singular 还支持其他中介平台。
通过在 Singular SDK 集成中添加代码片段,您可以从中介平台获取广告收入归因数据。这也允许您获取 SKAdNetwork 活动的广告收入数据。
从您的调解平台获取用户级广告收入后,Singular 就能将归属广告收入发送回媒体源,这些媒体源可以接受这些数据来运行 AdROAS 广告系列。
请参见 SDK 实施说明和代码片段[此处]。
添加 SKAdNetwork 支持
要为应用程序启用 SKAdNetwork 跟踪功能,请在初始化 Singular 之前启用skAdNetworkEnabled 配置选项。
托管模式(推荐)
在托管模式下,Singular 会根据您选择的转换模型自动为您管理 SKAdNetwork 转换值,您可以在 Singular 平台中设置转换模型。
要了解更多信息,请参阅了解 Singular 的转换值管理和SKAdNetwork 模型配置常见问题。有关与 Singular 一起使用 SKAdNetwork 的分步指南,请参阅如何开始使用 SKAdNetwork。
注意:SKAN 托管模式已在上述初始化代码片段中启用。请确保已设置这些配置项。
要在托管模式下启用 SKAdNetwork,请使用以下代码:
SingularConfig config = new SingularConfig('<SDK KEY>', '<SDK SECRET>');
config.skAdNetworkEnabled = true;
config.waitForTrackingAuthorizationWithTimeoutInterval = 300;
Singular.init(config);
手动模式
如果您已经有自己的策略和工具来管理 SKAdNetwork 转换值,则可在手动模式下启用 SKAdNetwork。
SingularConfig config = new SingularConfig('SDK KEY', 'SDK SECRET');
config.skAdNetworkEnabled = true;
config.manualSkanConversionManagement = true;
config.waitForTrackingAuthorizationWithTimeoutInterval = 300;
Singular.init(config);
然后,使用以下代码更新转换值:
ingular.skanUpdateConversionValue(conversionValue)
要跟踪转换值的变化,请使用以下回调函数:
config.conversionValueUpdatedCallback = (int conversionValue) {
print('Received conversionValueUpdatedCallback: ' + conversionValue.toString());
};
要检索当前转换值,请使用以下代码:
Singular.skanGetConversionValue().then((conversionValue) {
print('conversion value: ' + conversionValue.toString());
});
其他选项
跟踪卸载
要让Singular跟踪应用程序卸载情况,请向Singular提供APNS/FCM令牌,如下例所示:
// iOS
Singular.registerDeviceTokenForUninstall(apnsToken);
// Android
Singular.registerDeviceTokenForUninstall(fcmToken);
遵守数据隐私法
Singular提供隐私保护功能,帮助您与任何可能遵守消费者隐私法(如GDPR和CCPA(加州消费者隐私法))的合作伙伴合作。这些合作伙伴希望在最终用户同意共享其私人信息时得到通知。
如果你已经实施了一种征求用户同意共享其信息的方法,请使用limitDataSharing方法将用户的选择通知 Singular:
使用Singular.limitDataSharing(false)表示用户同意(选择加入)共享信息。
如果用户不同意,则使用Singular.limitDataSharing(true)。
Singular会在"用户隐私回传"(User Privacy Postbacks)中使用限制数据分享(LimitDataSharing)功能,并将此信息传递给需要的合作伙伴,以遵守相关法规。更多信息请参阅"用户隐私和限制数据共享"。
注意: 该方法的使用是可选的,但可能会有一些归属信息,只有在明确通知用户已选择的情况下,合作伙伴才会与Singular共享这些信息。
Singular.limitDataSharing方法 | |
---|---|
签名 | Singular.limitDataSharing (booleanshouldLimitDataSharing) |
说明 | 通知 Singular 用户同意(选择加入)共享私人数据。限制数据共享方法为您提供了一个选项,以控制您的应用程序是否将用户数据发送给第三方。如果您想根据用户偏好或隐私要求限制数据共享,这将非常有用。 |
使用示例 |
|
遵守 GDPR 的其他方法
Singular SDK 提供了多种方法来帮助您遵守 GDPR 政策,并让 Singular 了解用户是否同意追踪。
Singular.trackingOptIn 方法 | |
---|---|
说明 | 通知 Singular 用户同意(选择加入)跟踪。TrackingOptIn()方法用于向Singular服务器发送 "gdpr "事件。如果您不调用此方法,应用程序将继续跟踪用户,就像他们已经同意一样,但不会特别将他们标记为 GDPR opt-in。如果您的应用程序需要遵守 GDPR(《通用数据保护条例》),则应调用此功能,以确保正确记录用户同意。 |
使用示例 |
|
Singular.stopAllTracking 方法 | |
说明 |
停止此用户在此应用程序上的所有跟踪活动。 注意:调用此方法将有效禁用 SDK,即使在重新启动应用程序后也是如此(状态是持久的)!重新启用跟踪的唯一方法是调用 resumeAllTracking()。
|
使用示例 |
|
Singular.resumeAllTracking 方法 | |
说明 | 恢复此用户在此应用程序上的跟踪。 |
使用示例 |
|
Singular.isAllTrackingStopped 方法 | |
说明 | 检查此应用程序中该用户的跟踪状态。如果使用 StopAllTracking() 停止了跟踪且未恢复,则返回 true。 |
使用示例 |
|