KeenClientTD 4.1.1

KeenClientTD 4.1.1

测试已测试
语言语言 CC
许可 MIT
发布上次发布2024年4月

Komatsu Mitsunori 维护, Treasure Data 中的开发者



  • 作者:
  • Mitsunori Komatsu

Keen IO iOS SDK

Build Status

Keen IO iOS 客户端旨在易于开发,同时又极其灵活。我们的目标是让您决定哪些事件对您很重要,使用您自己的词汇来描述它们,并决定何时将它们发送到 Keen IO。

虽然这个仓库的名称暗示这个 SDK 仅为 iOS 设计,但它也可以通过以下的方式使用 Cocoa 版本在 Mac OS应用程序中使用。代码基础相同,但构建目标是不同的。:)

安装

安装客户端应该非常简单。如果不行,请通过 [email protected]告诉我们!

通用二进制文件

我们推荐安装 KeenClient 的方式是使用我们创建的通用二进制文件。我们为 CocoaiOS 提供了二进制文件。

虽然我们认为通用二进制文件使事情变得非常简单,但我们喜欢保持透明。我们喜欢 feedback,特别是以 pull request 的形式。

下载
解压缩 - Cocoa

解压缩存档。它应该包含一个名为“KeenClient-Cocoa”的文件夹,其中包含以下内容

  • libKeenClient-Cocoa.a
  • KeenClient.h
  • KeenProperties.h
  • KIOEventStore.h
将文件添加到 XCode - Cocoa

将“KeenClient-Cocoa”文件夹拖入您的XCode项目。

解压缩 - iOS

解压缩存档文件。它应包含一个名为“KeenClient”的文件夹,其中包含以下内容

  • libKeenClient-Aggregate.a
  • KeenClient.h
  • KeenProperties.h
  • KIOEventStore.h
添加文件到 XCode - iOS

将“KeenClient”文件夹拖入您的 XCode 项目。

构建设置

请确保将 CoreLocation.framework 添加到“链接二进制库”部分。

同时启用“其他链接器标志”下的“-ObjC”链接器标志。

就是这样!

使用方法

要使用此客户端配合 Keen IO API,您必须配置您的 Keen IO 项目 ID 及其访问密钥(如果需要账户,请在此处注册 - 免费提供)。

注册您的项目 ID 和访问密钥

使用项目 ID 和访问密钥注册 KeenClient 共享客户端。建议在您的应用程序代理之一中进行此操作

- (void)applicationDidBecomeActive:(UIApplication *)application
{
	[KeenClient sharedClientWithProjectId:@"your_project_id" andWriteKey:@"your_write_key" andReadKey:@"your_read_key"];
}

写入密钥是向 Keen IO 发送事件所必需的。读取密钥是用于在 Keen IO 进行分析所必需的。

[KeenClient sharedClientWithProjectIdеждаWriteKey:和ReadKey:]进行注册。从现在开始,您只需调用 objc [KeenClient sharedClient] 便可引用共享客户端。

添加事件

添加要跟踪的事件。以下是一个针对包含两个标签的应用程序的示例,我们想跟踪何时切换标签。

- (void)viewWillAppear:(BOOL)animated
{
  	[super viewWillAppear:animated];

  	NSDictionary *event = [NSDictionary dictionaryWithObjectsAndKeys:@"first view", @"view_name", @"going to", @"action", nil];
  	[[KeenClient sharedClient] addEvent:event toEventCollection:@"tab_views" error:nil];
}

首先在 JSON 可序列化值的任意字典中创建一个任意字典。我们支持

NSString, NSNumber, NSDate, NSDictionary, NSArray, and BOOL

JSON 规范不包括有关日期值的内容。在 Keen,我们知道日期对于跟踪很重要。Keen 经过其 API 以 ISO-8601 格式发送和接收日期。 KeenClient 会帮您处理。

键必须是字母数字字符,除了下划线字符(_),它可以出现在字符串中的任何位置,但不能出现在字符串的开头。例如,“view_name”是允许的,但不允许“_view_name”。

您可以添加任意数量的事件。 KeenClient 会将它们缓存在磁盘上,直到您准备好发送。

KeenClient 会自动将时间戳添加到您跟踪的每个事件中。如果您想用自己的值覆盖系统值,请参阅以下示例。注意,“timestamp”键已设置为头属性字典。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

   	NSDictionary *event = [NSDictionary dictionaryWithObjectsAndKeys:@"first view", @"view_name", @"going to", @"action", nil];
    NSDate *myDate = [NSDate date];
    KeenProperties *keenProperties = [[KeenProperties alloc] init];
   	keenProperties.timestamp = myDate;
    [[KeenClient sharedClient] addEvent:event
           	         withKeenProperties:keenProperties
       	              toEventCollection:@"tab_views"
   	                              error:nil];
}
全局属性

现在您可能正在想,“这看起来很容易。但我想在特定集合的每个事件中发送相同的属性怎么办?或者在每事件中发送?我们通过名为全局属性的东西帮您解决了这个问题。

全局属性是在每个事件中都发送的属性。例如,您可能希望始终捕获有关设备的信息,如 OS 版本、手机型号、方向等。

处理全局属性有两种方式 - 一种更简单但更有限,另一种更复杂但更强大。对于每种方式,在注册客户端后,您需要在使用的 KeenClient 实例上设置一个 Objective-C 属性。

基于字典的全局属性

为此,Objective-C属性命名为globalPropertiesDictionary。该属性值将是一个您定义的NSDictionary。每次添加一个事件时,客户端将查看此属性的值,并将其所有内容添加到用户定义的事件中。如果您想向每个事件添加一些静态属性,请使用此方法。

此为使用字典的示例

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    KeenClient *client = [KeenClient sharedClient];
   	client.globalPropertiesDictionary = @{@"some_standard_key": @"some_standard_value"};
}

如果用户定义的事件和全局属性中都指定了同名属性,则使用用户定义事件的属性。

基于块的全球属性

为此,Objective-C属性名为globalPropertiesBlock。属性值将是一个您定义的块。每次添加一个事件时,都会调用该块。客户端期望该块返回一个包含该事件集合全局属性的NSDictionary。如果要将许多动态属性(见下文)添加到每个事件中,请使用此方法。

这是使用块的一个示例

- (void)applicationDidBecomeActive:(UIApplication *)application
{
   	KeenClient *client = [KeenClient sharedClient];
    client.globalPropertiesBlock = ^NSDictionary *(NSString *eventCollection) {
   	    if ([eventCollection isEqualToString:@"apples"]) {
       	    return @{ @"color": @"red" };
        } else if ([eventCollection isEqualToString:@"pears"]) {
   	        return @{ @"color": @"green" };
        } else {
   	        return nil;
        }
   	};
}

该块包含一个字符串参数,对应于此类事件的具体名称。我们期望它返回一个您的自定义结构的NSDictionary。此示例未使用该参数,但您的可以实现!

因为我们支持此处的块,您可以为全局属性创建动态属性。例如,您可能想捕捉设备的方向,这显然可能在运行时改变。使用块,您可以在添加每个事件时使用函数式编程来询问操作系统当前的方向。非常实用,对吧?

另一个注意事项——您可以同时使用字典属性和块属性。如果定义了属性存在冲突,优先级顺序为:用户定义事件 > 块定义事件 > 字典定义事件。这意味着单个事件中放入的属性将始终显示,即使您在一个全局中定义了相同的属性也不例外。

地理定位

如同任何优秀的以移动设备为核心的服务,Keen支持地理定位,以便您可以跟踪事件发生的地点。默认情况下启用此功能。就像往常一样使用客户端,您的用户将被要求允许地理定位服务。所有事件都将自动标记当前的地理位置。

刷新当前位置

每次应用全新加载时,客户端会自动请求设备当前的位置。为了节省电池电量,它不会再次请求。您可以指示客户端再次要求设备的位置。只需调用即可。

[[KeenClient sharedClient] refreshCurrentLocation];
手动设置位置

您也可以手动设置位置。以下是一个示例

NSDictionary *event = [NSDictionary dictionaryWithObjectsAndKeys:@"first view", @"view_name", @"going to", @"action", nil];

KeenProperties *keenProperties = [[KeenProperties alloc] init];
CLLocation *location = [[CLLocation alloc] initWithLatitude:37.73 longitude:-122.47];
keenProperties.location = location;

[[KeenClient sharedClient] addEvent:event withKeenProperties:keenProperties toEventCollection:@"tab_views" error:nil];
在iOS 8+请求位置权限

iOS 8引入了请求授权的新方法,在自动将位置添加到事件之前需要执行一些额外步骤

  1. 添加以下一个或两个键到您的Info.plist文件:NSLocationWhenInUseUsageDescriptionNSLocationAlwaysUsageDescription
  2. 调用适当的授权方法以授权您的应用程序使用位置服务。authorizeGeoLocationWhenInUseauthorizeGeoLocationAlways 已经在此 SDK 的 3.2.16 版本中被添加。默认情况下,只要您在 Info.plist 文件中指定了 NSLocationWhenInUseUsageDescription,就会启用 authorizeGeoLocationWhenInUse,因此如果您选择 '当使用时' 路径,则不需要调用它。另一方面,必须显式调用 authorizeGeoLocationAlways

示例

[KeenClient authorizeGeoLocationAlways];
[KeenClient sharedClientWithProjectId:@"your_project_id" andWriteKey:@"your_write_key" andReadKey:@"your_read_key"];
上传事件到 Keen IO

将捕获到的事件上传到 Keen 服务。此操作必须显式进行。我们建议在应用程序被发送到后台时进行上传,但您可以根据需要随时进行(例如,如果您的应用程序通常有非常长的用户会话)。上传器启动它自己的后台线程,因此主 UI 线程不会被阻塞。

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    UIBackgroundTaskIdentifier taskId = [application beginBackgroundTaskWithExpirationHandler:^(void) {
        NSLog(@"Background task is being expired.");
    }];

    [[KeenClient sharedClient] uploadWithFinishedBlock:^(void) {
        [application endBackgroundTask:taskId];
    }];
}

在此示例中,上传是在后台任务中完成的,这样即使用户将应用程序置于后台,上传也可以继续。这里我们首先启动后台任务,开始上传,并在上传完成后结束后台任务。

如果您想在整个应用程序执行期间定期调用上传,您可以在任何时间通过在您的 KeenClient 实例上调用 uploadWithFinishedBlock 方法来实现。

[[KeenClient sharedClient] uploadWithFinishedBlock:nil];

重要提示:一次只执行一次上传是最佳实践。我们尽可能减少后台上传线程的数量,但如果您在一个循环中多次调用上传,您将给自己带来问题。

插件

Keen IO 可以解析您发送的数据并通过合并其他数据集来丰富它。这是通过“插件”的概念实现的。

要激活插件,您只需要在事件中“keen”命名空间内添加一些新的属性。有关我们插件的详细配置文档,请参阅此处

例如,假设我们想要启用IP 到 Geo 插件

KeenClient *client = [KeenClient sharedClient];
client.globalPropertiesDictionary = @{@"keen":
                                         @{
                                           @"addons":@[
                                                       @{
                                                           @"name":@"keen:ip_to_geo",
                                                           @"input":@{
                                                                   @"ip":@"ip_address"
                                                           },
                                                           @"output":@"ip_geo_info"
                                                       }
                                                   ]
                                               },
                                           @"ip_address":[self getIPAddress:YES]
                                         };

在此示例中,我们添加了一个全局属性,用于IP到Geo信息,该信息允许我们通过使用 [self getIPAddress:YES] 方法将设备的当前IP地址转换为设备的地理位置。

注意: [self getIPAddress:YES] 是一个您必须自己实现的定制方法,因为目前还没有内置的方法来获取设备的IP地址。我们成功使用了在这个帖子提出的几个解决方案。

调试

KeenClient 代码会执行大量日志记录,但默认情况下是关闭的。如果您想查看由您的客户端使用生成的日志行,您可以通过轻松启用日志记录来实现

[KeenClient enableLogging];

只需在任何您之前使用 KeenClient 的地方放置此代码。一个好的地方是在您应用程序的委托中。

要禁用日志记录,只需调用

[KeenClient disableLogging];
使用 Keen IO 进行分析
TO DO

常见问题

问:当设备离线时会发生什么?设备重新连接到wifi时,事件会自动发送吗?

答:我们的SDK处理离线数据收集,并内置限制以防止数据积聚过多。我们还处理重新发布事件,这样您就不必为此担心。

以下是它是如何工作的。您指定事件上传到Keen的时间(例如,当应用程序被置于后台时)。

如果此时播放器处于离线状态,其数据将在设备上收集,并不会发送到Keen IO。然而,下次它们触发发送事件(例如再次将应用置于后台)时,之前会话中的所有数据也将被发送(时间戳将反映事件实际发生的时间)。

更新日志

3.2.20
  • 由于CocoaPods版本问题,跳过了3.2.19。
  • 修复了由dispatch_sync递归调用引起的semaphore_wait_trap问题。
3.2.18
  • 修复了从KeenClient.h中错误删除disableGeoLocation方法调用的问题。
3.2.17
  • 修复了CocoaPods带来的3.2.16版本中的bug。
3.2.16
  • 增加了iOS 8中对requestWhenInUseAuthorizationrequestAlwaysAuthorization的支持。
3.2.15
  • 将GitHub文档更新至与keen.io中找到的文档一致。
  • 添加了KeenClient-Cocoa构建目标和通用二进制文件,以支持Mac OS X。
  • 将convertNSDateToISO8601添加到dispatch队列中。
  • 重构了信号量,以使用dispatch_sync,并清理了dispatch_retain的实例。
3.2.14
  • 修复了解析器警告。
  • 修复了返回为双指针的NSErrors的方法。
  • 在模拟器和设备目标中启用了ARC。
3.2.13
  • 更新了podspec,包括sqlite3的C源代码。
3.2.12
  • 跳过了3.2.11版本号,改为使用3.2.12来解决CocoaPods版本问题。
  • 将KeenClient转换为使用ARC。
  • 将所有以keen_io_前缀开头的SQLite文件重命名。
  • 将keen_io_sqlite3.h的导入移动到KIOEventStore.m中。
  • 添加了sdkVersion类方法。
  • 用基于SQLite的日期转换(线程安全)替换了NSDateFormatter的使用。
  • 修复了KEEN_LOGGING_宏。
  • 在getEvents中添加了对resetPendingEvents的调用。
  • 修复了KIOEventStore实现引起的实例客户端问题。
3.2.10
  • 在prepareJSONData中修复了数组分配/释放的bug。
  • 在KIOEventStore中添加了排队功能,以确保SQLite调用是序列化的。
  • 添加了sqlite-amalgamation库,以消除对libsqlite3.dylib的依赖。
  • 将版本字符串添加到日志中。
3.2.9
  • 用KIOEventStore替换了文件系统的缓存目录。
3.2.8
  • 上传完成后,修复了具有一致性固定的块。
3.2.7
  • 支持在事件中发送附加组件。
3.2.6
  • 即使在没有事件要上传的情况下,也会始终调用上传回调。
3.2.5
  • 当本地缓存目录不可用时,不要抛出异常并导致应用崩溃。
  • 移除了ISO8601DateFormatter的依赖。
  • 使用Grand Central Dispatch以避免每次上传调用时都启动一个线程。
3.2.4
  • 为 cocoapods 清理了语义版本(不知为何在3.2.2和3.2.3之间迷惑了)。
3.2.2
  • 支持iOS 7和ARM64。
  • 使用NSJONSerialization代替JSONKit的依赖。
3.2.1
  • 将项目令牌改为项目ID。
  • 添加了对读取和写入作用域密钥的支持。
  • 添加了对travis的支持。

待办事项

  • 支持分析API。
  • 原生iOS可视化。

问题和支持

如果您有任何问题、bug或建议,请通过GitHub Issues进行报告。或者,您可以在users.keen.io随时与我们聊天。我们乐于倾听您的反馈和想法!

贡献

这是一个开源项目,我们欢迎社区参与!请通过请求和问题联系我们。