TreasureData-iOS-SDK 1.2.0

TreasureData-iOS-SDK 1.2.0

测试已测试
Lang语言 Obj-CObjective C
许可 Apache-2.0
发布最后发布2024 年 7 月

Mitsunori KomatsuTreasure Data 开发者 维护。



 
依赖
KeenClientTD= 4.1.1
GZIP= 1.3.2
 

  • 作者
  • mitsu,huylenq 和 tung-vu-td

Treasure Data iOS SDK

iOS 和 tvOS SDK,用于Treasure Data。使用此 SDK,您可以轻松地将应用程序中的事件导入 Treasure Data。截至 0.9.0 版本,此 SDK 支持 iOS 12 及以上版本以及支持的 tvOS 12 及以上版本。

此外,还有一个用 Swift 编写的替代 SDK,可在 https://github.com/recruit-lifestyle/TreasureDataSDK 上找到。请注意,然而,它不支持主流 TD SDK 中的当前 GDPR 功能。

迁移到 1 版本

版本 1 有一些主要更改,与以前版本不兼容。如果您是从 0.9.0 或更早版本升级,您的代码将不会在没有以下步骤的情况下正确运行

  • API 端点已更改为摄入端点。默认值是 https://us01.records.in.treasuredata.com
  • initializeApiEndpoint: API 现在不可用,请使用 initializeWithApiKey:apiEndpoint: 代替。
  • 服务器端上传时间戳功能已删除。如果您需要此功能,请联系我们的支持团队。
  • uuid 现在是保留的列名。如果你尝试向事件的 uuid 键添加值,你将不会在数据库中看到该列显示。

安装

有许多方法可以安装此库。

CocoaPods

CocoaPods 是设置 SDK 所必需的。如果您尚未安装,请首先进行安装。

$ gem install cocoapods

然后,在您的 Podfile 中添加以下行。

pod 'TreasureData-iOS-SDK', '= 1.0.1'

将此行添加到您的 Podfile 中(通常位于文件开头)。

use_frameworks!

最后,执行 'pod install'。

$ pod install

请记住,通过打开 .xcworkspace 文件而不是 .xcodeproj 文件来重新打开您的项目。

Swift Package Manager

您可以通过 Xcode 安装它:文件 > Swift Packages > 添加包依赖并输入 https://github.com/treasure-data/td-ios-sdk.git

或者将此行添加到 dependencies 数组中的 Package.swift 文件。

.package(url: "https://github.com/treasure-data/td-ios-sdk.git", .upToNextMajor(from: "1.0.1"))

框架

从 0.9.0 版本开始,我们不再支持独立的框架。

Objective-C 中的使用

导入 SDK 标准头文件

#import <TreasureData-iOS-SDK/TreasureData.h>

注册 TreasureData API 密钥

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [TreasureData initializeWithApiKey:@"your_api_key"];
}

我们建议使用 SDK 的只写 API 密钥。要获取一个,请

  1. 登录到 Treasure Data 控制台 http://console.treasuredata.com
  2. 访问您的个人资料页面 http://console.treasuredata.com/users/current
  3. 在“API 密钥”面板下输入您的密码;
  4. 在面板的下方,在“只写 API 密钥”部分,可以复制 API 密钥或点击“生成新的”并复制新的 API 密钥。

将事件添加到本地缓冲区

要将事件添加到本地缓冲区,您可以通过调用 TreasureData 的 addEventaddEventWithCallback API 实现。

- (IBAction)clickButton:(id)sender {
    [[TreasureData sharedInstance] addEventWithCallback:@{
                       @"name": @"boo bar",
                       @"age": @42,
                       @"comment": @"hello world"
                   }
                   database:@"testdb"
                      table:@"demotbl"
                  onSuccess:^(){
                      NSLog(@"addEvent: success");
                  }
                    onError:^(NSString* errorCode, NSString* message) {
                        NSLog(@"addEvent: error. errorCode=%@, message=%@", errorCode, message);
                    }];
                    
    // Or, simply...
    //   [[TreasureData sharedInstance] addEvent:@{
    //                     @"name": @"boo bar",
    //                     @"age": @42,
    //                     @"comment": @"hello world"
    //                 }
    //                 database:@"testdb"
    //                    table:@"demotbl"];

指定您想要导入事件的数据库和表。数据库和表的总长度必须小于 129 个字符。每个表都将缓存不超过 10000 个事件。

此外,事件中的键长度不得超过 256 个字符,并且值长度不得超过 10000 个字符。

上传缓冲事件到TreasureData

要将缓冲事件上传到Treasure Data,您可以调用Treasure Data的uploadEventsuploadEventsWithCallback API。

- (void)applicationDidEnterBackground:(UIApplication *)application {
	__block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
		[application endBackgroundTask:bgTask];
		bgTask = UIBackgroundTaskInvalid;
	}];

    // You can call this API to uplaod buffered events whenever you want.
	[[TreasureData sharedInstance] uploadEventsWithCallback:^() {
			[application endBackgroundTask:bgTask];
			bgTask = UIBackgroundTaskInvalid;
		}
		onError:^(NSString *code, NSString *msg) {
			[application endBackgroundTask:bgTask];
			bgTask = UIBackgroundTaskInvalid;
		}
	];

    // Or, simply...
    //  [[TreasureData sharedInstance] uploadEvents];

上传缓冲事件的时间取决于您应用的特性,但以下时机至少是上传的好时机。

  • 当前屏幕关闭或切换到后台时
  • 关闭应用程序时

发送的事件将在缓冲几分钟后才被导入到Treasure Data存储中。

在tvOS中,缓存存储位于缓存目录中,随时可能被清除。强烈建议尽可能频繁地调用上传事件API,以防止数据丢失。

重试上传和去重

此SDK通过结合以下功能以完全一次风格导入事件。

  • 此SDK通过添加唯一键和重试来保留缓冲事件,直到确认事件已上传并存储在服务器端(至少一次)。
  • 默认情况下,服务器端会记住过去1小时内所有事件的唯一键,以防止重复导入(最多一次)。

由于去重窗口默认为1小时,因此不要保留超过1小时的缓冲事件,以避免重复事件。

默认值

如果您想将事件添加到表、数据库或任何表或数据库,并自动为密钥设置值,请设置默认值。如果您为同一密钥设置了多个默认值,则新添加的事件将应用默认值并按以下顺序覆盖

  1. 首先应用针对所有表和数据库的默认值。
  2. 然后应用针对数据库中所有表的默认值。
  3. 接下来应用针对添加事件的表的默认值。
  4. 之后应用针对添加事件表和数据库的默认值。
  5. 最后,如果事件有该键的值,则该值将覆盖所有默认值。

设置默认值

[[TreasureData sharedInstance] setDefaultValue:@"Value" forKey:@"key" database:nil table:nil]; // Targeting all databases and tables
[[TreasureData sharedInstance] setDefaultValue:@"Value" forKey:@"key" database:"database_name" table:nil]; // Targeting all tables of database "database_name"
[[TreasureData sharedInstance] setDefaultValue:@"Value" forKey:@"key" database:nil table:"table_name"]; // Targeting all tables with "table_name"
[[TreasureData sharedInstance] setDefaultValue:@"Value" forKey:@"key" database:"database_name" table:"table_name"]; // Targeting table "table_name" of database "database_name"

获取默认值

NSString *defaultValue = [[TreasureData sharedInstance] defaultValueForKey:@"key" database:"database_name" table:"table_name"]; // Get default value for key targeting database "database_name" and table "table_name".

删除默认值

[[TreasureData sharedInstance] removeDefaultValueForKey:@"key" database:"database_name" table:"table_name"]; // Only remove default values targeting database "database_name" and table "table_name".

开始/结束会话

调用 startSession 方法时,SDK 会生成一个会话 ID,直到调用 endSession。会话 ID 以列名 "td_session_id" 输出。同时,startSessionendSession 方法会添加一个包含 {"td_session_event":"start" 或 "end"} 的事件。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
	[TreasureData initializeWithApiKey:@"your_api_key"];
	[[TreasureData sharedInstance] setDefaultDatabase:@"testdb"];
	[[TreasureData sharedInstance] startSession:@"demotbl"];
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
	[[TreasureData sharedInstance] endSession:@"demotbl"];

	__block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
		[application endBackgroundTask:bgTask];
		bgTask = UIBackgroundTaskInvalid;
	}];

	[[TreasureData sharedInstance] uploadEventsWithCallback:^() {
			[application endBackgroundTask:bgTask];
			bgTask = UIBackgroundTaskInvalid;
		}
		onError:^(NSString *code, NSString *msg) {
			[application endBackgroundTask:bgTask];
			bgTask = UIBackgroundTaskInvalid;
		}
		// Outputs =>>
		//   [{"td_session_id":"cad88260-67b4-0242-1329-2650772a66b1",
		//		"td_session_event":"start", "time":1418880000},
		//
		//    {"td_session_id":"cad88260-67b4-0242-1329-2650772a66b1",
		//		"td_session_event":"end", "time":1418880123}
		//    ]
	];

如果你想处理以下情况,请使用一对类方法 startSessionendSession 进行全局会话跟踪

  • 用户打开应用程序并使用 startSession 启动会话跟踪。让我们称这个会话为会话#0
  • 用户切换到主屏幕并使用 endSession 结束会话
  • 用户重新打开应用程序并在默认的 10 秒内重新启动会话跟踪。但你想将这个新会话视为与会话#0 相同的会话
- (void)applicationDidBecomeActive:(UIApplication *)application
{
	[TreasureData startSession];
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
	[TreasureData endSession];
}

在这种情况下,你可以使用 getSessionId 类方法获取当前会话 ID

- (void)applicationDidBecomeActive:(UIApplication *)application
{
	[TreasureData startSession];
    NSLog(@"Session ID=%@", [TreasureData getSessionId]);
}

检测是否为首次运行

您可以使用 isFirstRun 方法轻松检测是否为首次运行,然后使用 clearFirstRun 清除标志。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
		:
    if ([[TreasureData sharedInstance] isFirstRun]) {
        [[TreasureData sharedInstance] addEventWithCallback:@{ @"event": @"installed" }
                               database:@"testdb"
                                  table:@"demotbl"
                              onSuccess:^(){
                                  [[TreasureData sharedInstance] uploadEventsWithCallback:^() {
                                      [[TreasureData sharedInstance] clearFirstRun];
                                    }
                                    onError:^(NSString* errorCode, NSString* message) {
                                      NSLog(@"uploadEvents: error. errorCode=%@, message=%@", errorCode, message);
                                    }
                                   ];
                                }
                                onError:^(NSString* errorCode, NSString* message) {
                                    NSLog(@"addEvent: error. errorCode=%@, message=%@", errorCode, message);
                                }];
    }

关于错误代码

addEventWithCallbackuploadEventsWithCallback 方法将带有一个 errorCode 参数的 onError 块。这个参数对于了解错误的原因类型很有用。以下是以下错误代码。

  • init_error : 初始化失败。
  • invalid_param : 传递给 API 的参数无效
  • invalid_event : 事件无效
  • data_conversion:数据转换为JSON格式失败
  • storage_error:在存储中读取/写入数据失败
  • network_error:由于网络问题,无法与服务器通信
  • server_response:服务器返回了错误响应

附加配置

端点

API端点(默认:https://us01.records.in.treasuredata.com)可以使用+[TreasureData initializeWithApiKey:apiEndpoint]指定

[TreasureData initializeWithApiKey:@"your_api_key" apiEndpoint: @"https://specifying-another-endpoint.com"];

加密密钥

如果您已通过initializeEncryptionKey类方法设置了加密密钥,我们的SDK在调用addEventaddEventWithCallback方法时会将事件数据以加密形式保存。

[TreasureData initializeEncryptionKey:@"hello world"];

[[TreasureData sharedInstance] addEventWithCallback: ....];

默认数据库

[[TreasureData sharedInstance] setDefaultDatabase:@"testdb"];

[[TreasureData sharedInstance] addEventWithCallback:@{ @"event": @"clicked" } table:@"demotbl"]

自动将设备的UUID添加到每个事件中

如果您调用enableAutoAppendUniqId,将自动将设备的UUID添加到每个事件中。此值在应用卸载或调用resetUniqId之前不会更改。

[[TreasureData sharedInstance] enableAutoAppendUniqId];

它将值输出为列名td_uuid

获取UUID和重置UUID

您可以使用以下API在任何时间获取当前UUID(td_uuid)。请注意,如果调用resetUniqId,则此UUID将更改。

NSString *td_uuid = [[TreasureData sharedInstance] getUUID];

您也可以使用以下API在任何时间重置UUID(td_uuid)。

[[TreasureData sharedInstance] resetUniqId];

自动将本地时间添加到每个事件记录中(默认启用)

默认情况下,本地时间戳将自动添加到事件的time键中。如果您不添加time键到事件中,而是使用disableAutoAppendLocalTimestamp,服务器将添加服务器端时间戳到time列。您还可以通过自定义列自动跟踪本地时间。如果是这样,则time列将具有服务器端时间戳。

// Use local time as `time` column
[[TreasureData sharedInstance] enableAutoAppendLocalTimestamp];

// Add local time as a customized column name
[[TreasureData sharedInstance] enableAutoAppendLocalTimestamp:@"clientside_time"];

// Disable auto append local time
[[TreasureData sharedInstance] disableAutoAppendLocalTimestamp];

自动将UUID添加到每个事件记录中

如果您调用 enableAutoAppendRecordUUID,则UUID将自动添加到每个事件记录中。每个事件都有一个不同的UUID。

[[TreasureData sharedInstance] enableAutoAppendRecordUUID];

// If you want to customize the column name, pass it to the API
[[TreasureData sharedInstance] enableAutoAppendRecordUUID:@"my_record_uuid"];

默认情况下,它将值输出为列名 record_uuid

自动将广告ID添加到每个事件记录中

如果您调用 enableAutoAppendAdvertisingIdentifier,则广告ID将自动添加到每个事件记录中。

为了使此功能正常运行,您必须在“链接库”构建阶段链接Ad Support框架。用户也必须在他们的iOS设备上不开启“限制广告跟踪”功能,否则Treasure Data会将填充零的字符串作为广告ID(从Ad Support框架获得的值)发送。

从iOS 14开始,您必须使用AppTrackingTransparency框架明确请求用户对广告标识符的授权。有关如何在AppTrackingTransparency上实现这一要求,请参阅Apple官方文档。

如果您启用此功能,请注意您提交应用程序进行App Store审核时,必须声明获取广告标识符的正确原因。

[[TreasureData sharedInstance] enableAutoAppendAdvertisingIdentifier];

// If you want to customize the column name, pass it to the API
[[TreasureData sharedInstance] enableAutoAppendAdvertisingIdentifier:@"custom_ad_id_column"];

默认情况下,它以列名 td_maid 输出值。

自动将设备型号信息添加到每个事件中

如果您调用 enableAutoAppendModelInformation,则设备型号信息将自动添加到每个事件中。

[[TreasureData sharedInstance] enableAutoAppendModelInformation];

它输出以下列名和值:

  • td_device : UIDevice.model
  • td_model : UIDevice.model
  • td_os_ver : UIDevice.model.systemVersion
  • td_os_type : "iOS"

自动将应用程序版本信息添加到每个事件中

如果您调用 enableAutoAppendAppInformation,则应用程序版本信息将自动添加到每个事件中。

[[TreasureData sharedInstance] enableAutoAppendAppInformation];

它输出以下列名和值:

  • td_app_ver : 核心基金键 CFBundleShortVersionString
  • td_app_ver_num : 核心基金键 CFBundleVersion

自动向每个事件添加区域配置信息

如果调用 enableAutoAppendLocaleInformation,将自动将区域配置信息添加到每个事件中。

[[TreasureData sharedInstance] enableAutoAppendLocaleInformation];

它输出以下列名和值:

  • td_locale_country : [[NSLocale currentLocale] objectForKey: NSLocaleCountryCode]
  • td_locale_lang : [[NSLocale currentLocale] objectForKey: NSLocaleLanguageCode]

使用服务器端上传时间戳

如果只想使用服务器端上传时间戳(而不是客户端记录的 addEvent 调用时的设备时间),请使用 enableServerSideUploadTimestamp

// Use server side upload time as `time` column
[[TreasureData sharedInstance] enableServerSideUploadTimestamp];

// Add server side upload time as a customized column name
[[TreasureData sharedInstance] enableServerSideUploadTimestamp:@"server_upload_time"];

启用/禁用调试日志

[TreasureData enableLogging];
[TreasureData disableLogging];

自动跟踪的事件

请注意,所有这些默认都是 *禁用的,您必须分别为每个类别明确启用它。

应用生命周期事件

可以通过以下方式启用

[[TreasureData sharedInstance] enableAppLifecycleEvent];

有三种类型的应用生命周期事件被追踪:TD_IOS_APP_OPENTD_IOS_APP_INSTALLTD_IOS_APP_UPDATE(写入到td_ios_event列)。

追踪安装事件的示例

"td_ios_event" = "TD_IOS_APP_INSTALL";
"td_app_ver" = "1.1";
"td_app_ver_num" = 2;

应用内购买事件

TreasureData SDK能够自动追踪IAP SKPaymentTransactionStatePurchased事件,无需编写自己的事务观测器。

[[TreasureData sharedInstance] enableInAppPurchaseEvent];

默认情况下是禁用的。这与appLifecycleEventcustomEvent有所不同。其他两个,由于历史原因,是持久设置,意味着它们的状态将保存跨应用启动。inAppPurchaseEvent的行为像一个普通对象选项,并不会保存。您必须在初始化新的TreasureData实例(可能是带有initializeWithApiKeysharedInstance)之后启用它。

IAP事件的示例

"td_ios_event": "TD_IOS_IN_APP_PURCHASE",
"td_iap_transaction_identifier": "1000000514091400",
"td_iap_transaction_date": "2019-03-28T08:44:12+07:00",
"td_iap_quantity": 1,
"td_iap_product_identifier": "com.yourcompany.yourapp.yourproduct", ,
"td_iap_product_price": 0.99,
"td_iap_product_localized_title": "Your Product Title",
"td_iap_product_localized_description": "Your Product Description",
"td_iap_product_currency_code": "USD",  // this is only available on iOS 10 and above

我们将做一个独立的SKProductsRequest来获取完整的产品信息。如果请求失败,带有"td_iap_product_"前缀的字段将变为null。另外,请注意,currency_code仅从iOS 10开始可用。

配置文件API

fetchUserSegments

此功能默认情况下未在账户上启用,请联系支持以获取更多信息。重要!您必须设置TreasureData的sharedInstance的cdpEndpoint属性。使用示例

// Set cdpEndpoint when initialize TreasureData  
[[TreasureData sharedInstance] setCdpEnpoint: @"[your cdp endpoint goes here]"]

// Call fetchUserSegments to get user segments as NSArray

NSArray *audienceTokens = @[@"Your Profile API (Audience) Token here"];
NSDictionary *keys = @{@"your_key": @"your_value"};
NSDictionary<TDRequestOptionsKey, id> *options = @{
    TDRequestOptionsTimeoutIntervalKey: [NSNumber numberWithInteger: 10],
    TDRequestOptionsCachePolicyKey: [NSNumber numberWithUnsignedInteger: NSURLRequestReloadIgnoringCacheData]
};
[[TreasureData sharedInstance] fetchUserSegments:audienceTokens
                                            keys:keys
                                         options:options
                               completionHandler:^(NSArray * _Nullable jsonResponse, NSError * _Nullable error) {
   NSLog(@"fetchUserSegments jsonResponse: %@", jsonResponse);
   NSLog(@"fetchUserSegments error: %@", error);
}];

GDPR 合规性

此 SDK 提供了一些方便的方法,可以轻松地关闭对设备的跟踪,无需使用大量的嵌套 if-else 语句。

// Opt-out of your own events
[[TreasureData sharedInstance] disableCustomEvent];
// Opt-out of TD generated events
[[TreasureData sharedInstance] disableAppLifecycleEvent];
[[TreasureData sharedInstance] disableInAppPurchaseEvent];

可以通过调用 enableCustomEventenableAppLifecycleEvent 来选择重新开启这些功能。请注意,这些设置会被持久化保存,因此即使在应用程序启动之间也仍然有效。通常,应在这些方法被调用以反映用户的选择时调用,而不是在每次初始化 SDK 时。默认情况下,自定义事件是启用的,而应用程序生命周期的事件是禁用的。

  • 使用 resetUniqId 重置设备在后续事件中的标识。将 td_uuid 随机化为另一个值,并通过额外的具有以下内容的 {"td_ios_event": "forget_device_id", "td_uuid": <old_uuid>} 事件发送到 defaultTable

tvOS

该 SDK 支持苹果 tvOS 12 及以上版本。API 和其行为与在 iOS 应用程序中使用的大致相同,除了

! 在 tvOS 中,缓存存储存储在缓存目录中,可以随时清除。强烈建议尽可能频繁地调用上传事件 API,以防止数据丢失。

故障排除

启用“数据保护”功能后,TD iOS SDK 偶尔会崩溃

  • 如果您的应用在 UIApplicationDelegate applicationDidEnterBackground 中调用 SDK 的 API,例如 TreasureData#endSession,请检查是否在 iOS 锁定几秒后调用 SDK 的 API。如果是这样,请将耗时要长且在 SDK 的 API 运行之前在后台调用的其他任务。
- (void)applicationWillResignActive:(UIApplication *)application
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // Some tasks that can take more than 10 seconds.
    });
}

Swift 使用示例

详细请参考此示例项目(https://github.com/treasure-data/td-ios-sdk/tree/master/TreasureDataExampleSwift)。

Xcode 兼容性

当前版本使用 XCode v10.2 编译和测试。