浏览器版本低!无法浏览完整内容,建议升级或更换浏览器。
轨迹追踪
下载开发文档
简介

iOS鹰眼轨迹SDK可以根据开发者自定义的定位周期和上传周期,自动地采集设备的位置信息,回传到鹰眼服务端,形成连续的轨迹。开发者可以为每个轨迹点添加附加信息,也可以对定位选项、采集周期与上传周期、缓存容量等进行自定义设置。SDK支持后台运行,断网时自动缓存,网络恢复后自动重连上传。

SDK与服务端采用TCP长连接与HTTPS通信,所有数据经过压缩和加密,保障数据安全,省电省流量。 轨迹追踪是鹰眼SDK中最基础、最核心的功能。通过类BTKAction中相应的接口,控制轨迹服务与轨迹采集的开启和停止,操作结果通过BTKTraceDelegate协议中相应的方法回调给开发者。下面首先对涉及到的基本概念进行介绍,之后会对各功能进行阐述。

注意:

开发者在百度地图鹰眼自行上传数据与百度地图开放平台无关,开发者应对上传数据的合法性负责,并确保不侵犯他人合法权益。若上传数据包含用户隐私信息,包括但不限于用户名、手机号、身份ID等,请开发者确保已获取用户的授权同意并由开发者自行加密以保障用户隐私安全,百度地图开放平台不对开发者自行上传的用户数据进行校验和加密。

基础概念

轨迹服务与轨迹采集

1. 轨迹服务的含义:轨迹服务负责和服务端建立并保持长连接,接收服务端的推送消息,并将客户端的轨迹数据尽快地上传到服务端。

2. 轨迹采集的含义:SDK通过访问iOS系统定位服务获取当前设备的位置信息。

3. 服务与采集的关系:与采集相比,服务是一个更广的概念。虽然采集的开启与结束和服务的开启与结束是独立控制的,但他们的调用顺序也有一定的要求:调用startGather和stopGather之前必须先调用startService,并且调用stopService时,SDK会自动stopGather。一个典型的使用场景是:

startService -> startGather -> stopGather -> startGather -> stopGather -> … -> stopService 也就是开启服务之后,在需要采集轨迹的时候就调用startGather,不需要采集轨迹的时候就调用stopGather,最后停止服务。

采集周期与上传周期

SDK以采集周期为间隔,周期性地采集当前设备的位置信息;以上传周期为间隔,周期性地将若干轨迹点上传至鹰眼服务端。

后台保活

当APP切换至后台,且期望尽量保持存活并持续定位追踪轨迹时,开发者需参照配置工程--> plist文件设置,在APP声明定位权限时选择“同时需要前台和后台定位”,并且在最终用户授权时将APP定位权限设为“始终”,此时不论APP在前台还是后台,APP被杀死概率较低。

APP可定期检测用户定位授权状态,当检测到APP定位权限设不为“始终”时,可在适当的时机提示用户设置权限。以上操作均需严格遵守《百度地图开放平台产品和服务隐私政策》

服务初始化

通过BTKAction类的 – (BOOL)initInfo:(BTKServiceOption *)option; 方法设置SDK运行所需要的基础信息。包括AK、mcode、轨迹服务的ID以及是否需要保活。调用SDK的任何接口之前,必须先调用此方法,否则SDK的各功能无法正常运行。

以下代码片段表示,设置SDK运行时需要的基础信息:

BTKServiceOption *sop = [[BTKServiceOption alloc] initWithAK:@"asdf1234asdf1234" mcode:@"com.yingyan.sdk" serviceID:100000 keepAlive:false];
[[BTKAction sharedInstance] initInfo:sop];
轨迹服务控制

轨迹服务的控制分为开启轨迹服务(startService)和停止轨迹服务(stopService)两个接口。

开启服务

通过BTKAction类的 - (void)startService:(BTKStartServiceOption *)option delegate:(id <BTKTraceDelegate>)delegate; 方法开启轨迹服务,操作结果通过 BTKTraceDelegate 协议的 -(void)onStartService:(BTKServiceErrorCode) error; 方法回调给开发者。

开启服务时需要指定BTKStartServiceOption类型的配置信息,目前BTKStartServiceOption 类中只有entityName一个属性。该entityName在SDK的运行过程中有举足轻重的作用:

1. 开启轨迹服务之后,SDK会以此entityName的身份登录到服务端

2. 在轨迹服务运行期间,收到的地理围栏报警信息都来自于被监控对象为此entityName的地理围栏

3. 在轨迹服务运行期间,采集到的轨迹数据也隶属于此entityName名下

4. 开启轨迹服务之后,如果有之前遗留的缓存数据,也会将其全部上传至服务端(所有entity的缓存数据都会上传)

以下代码片段表示,开启轨迹服务:

// 设置开启轨迹服务时的服务选项,指定本次服务以“entityA”的名义开启
BTKStartServiceOption *op = [[BTKStartServiceOption alloc] initWithEntityName:@"entityA"];
// 开启服务
[[BTKAction sharedInstance] startService:op delegate:self];

停止服务

停止轨迹服务时,SDK会和服务端断开连接。在此之前,如果当前登录的entity有断网缓存的数据,则将其上传至服务端。以上操作均要求网络畅通,否则只是停止轨迹服务,缓存数据会由SDK持久化保存,待下次开启轨迹服务后,网络畅通的情况下,由SDK自动继续上传。

以下代码片段表示,停止轨迹服务:

[[BTKAction sharedInstance] stopService:self];
轨迹采集控制

轨迹采集的控制分为开启采集(startGather)和结束采集(stopGather)两个接口。开启采集和结束采集都必须在开启轨迹服务之后才可以调用。开启采集之后,SDK会在每个采集周期获取当前设备的位置信息,停止采集之后,SDK 不再获取当前设备的位置信息。

开始采集

通过BTKAction 类的 -(void)startGather:(id <BTKTraceDelegate>)delegate; 方法开始采集轨迹,操作结果通过 BTKTraceDelegate 协议的-(void)onStartGather:(BTKGatherErrorCode) error; 方法回调给开发者。

以下代码片段表示,开始采集:

[[BTKAction sharedInstance] startGather:self];

停止采集

通过BTKAction 类的 -(void)stopGather:(id <BTKTraceDelegate>)delegate; 方法停止采集轨迹,操作结果通过 BTKTraceDelegate 协议的-(void)onStopGather:(BTKGatherErrorCode) error; 方法回调给开发者。

以下代码片段表示,停止采集:

[[BTKAction sharedInstance] stopGather:self];

对于轨迹服务和轨迹采集的操作接口,应当在收到上一次操作的回调之后,根据执行结果,再发起下一次调用。比如在onStartService回调中,如果轨迹服务开启成功,再调用startGather接口。

自定义字段上传

每个轨迹点都可能有一些和具体业务相关的数据,iOS鹰眼轨迹SDK支持开发者将这些数据作为轨迹点的自定义数据,“附加”到这个轨迹点上。

SDK在每个采集周期会回调 BTKTraceDelegate 协议中的 -(NSDictionary *)onGetCustomData; 方法,将其返回值作为当前采集周期采集的轨迹点的自定义字段的值。SDK会解析此方法返回的字典,将key认为是自定义字段的名称,将value认为是自定义字段的值。需要注意的是,字典中的key必须是已经存在的 track属性字段。开发者可以通过鹰眼轨迹管理台,设置某个service的 track属性字段。下面我们通过一个例子,来进一步说明如何上传轨迹点的自定义字段值:

比如当前在开发一款跑步类的APP,可能需要记录每个轨迹点所对应的心率信息,那么可以通过以下几个步骤实现这一点:

1. 创建自定义字段

通过鹰眼轨迹管理台,为当前service添加一个track属性字段,其字段名称为‘heart_rate’,字段描述为“心率”,字段类型为int。

2. 获取自定义字段的值

通过心率带或带有心率检测功能的外部设备获取心率,并通过其相应的接口将心率数据传入APP。定义一个字典类型的变量,包含一个名为heart_rate的键,并设置其初始值。假设为additional_data[‘heart_rate’] = 60

3. 定时更新自定义字段的值

每当APP获取到最新的心率数据时,更新这个字典中heart_rate的值为最新的心率数据。

-(NSDictionary *)onGetCustomData; 方法的实现非常简单,只需要return这个字典即可。

通过以上步骤,SDK在每个采集周期回调这个方法时,就获取到了最新的心率数据,并将此心率数据“附加”在了当前的轨迹点上。

无论是通过 queryEntityList方法查询实时位置,还是通过getTrackHistory方法查询历史轨迹,这些心率数据都会作为轨迹的“附加”数据呈现出来。

补充说明一点,每个采集周期对应轨迹点的速度、方向、海拔高度、定位精度的值,作为轨迹数据的一部分,SDK会自动采集上传,不需要额外实现此方法去指定。

以下代码示例表示,当前开启轨迹服务时指定的serviceID下,已经在轨迹管理台中添加了名为“intTest”、“doubleTest”、“stringTest” 这3个track属性字段,在每个采集周期采集的轨迹点,都将这3个字段赋予一个随机值,“附加”在该轨迹点上。

-(NSDictionary *)onGetCustomData {
NSMutableDictionary *customData = [NSMutableDictionary dictionaryWithCapacity:3];
NSArray *intPoll = @[@5000, @7000, @9000];
NSArray *doublePoll = @[@3.5, @4.6, @5.7];
NSArray *stringPoll = @[@"aaa", @"bbb", @"ccc"];
int randomNum = arc4random() % 3;
// intTest doubleTest stringTest这3个自定义字段需要在轨迹管理台提前设置才有效
customData[@"intTest"] = intPoll[randomNum];
customData[@"doubleTest"] = doublePoll[randomNum];
customData[@"stringTest"] = stringPoll[randomNum];
return [NSDictionary dictionaryWithDictionary:customData];
}
消息推送回调

在开启轨迹服务之后,停止轨迹服务之前,iOS鹰眼轨迹SDK在运行期间内会随时通过 BTKTraceDelegate 协议的 -(void)onGetPushMessage:(BTKPushMessage *)message; 回调方法,向开发者推送消息。推送的消息为 BTKPushMessage 类型,其中type 属性代表推送消息的类型,content 属性代表推送消息的内容。

消息分类

目前iOS鹰眼轨迹SDK只会推送服务端地理围栏报警和客户端地理围栏报警2种类型的消息,对应的 type 属性的值分别为 0x03 和 0x04。

消息内容

对于服务端地理围栏报警和客户端地理围栏报警这2种消息类型对应的消息内容,按照 BTKPushMessageFenceAlarmContent 类来解析。

以下代码示例展示了,如何解析消息推送:

- (void)onGetPushMessage:(BTKPushMessage *)message {
NSLog(@"收到推送消息,消息类型: %@", @(message.type));
if (message.type == 0x03) {
BTKPushMessageFenceAlarmContent *content = (BTKPushMessageFenceAlarmContent *)message.content;
if (content.actionType == BTK_FENCE_MONITORED_OBJECT_ACTION_TYPE_ENTER) {
NSLog(@"被监控对象 %@ 进入 服务端地理围栏 %@ ", content.monitoredObject, content.fenceName);
} else if (content.actionType == BTK_FENCE_MONITORED_OBJECT_ACTION_TYPE_EXIT) {
NSLog(@"被监控对象 %@ 离开 服务端地理围栏 %@ ", content.monitoredObject, content.fenceName);
}
} else if (message.type == 0x04) {
BTKPushMessageFenceAlarmContent *content = (BTKPushMessageFenceAlarmContent *)message.content;
if (content.actionType == BTK_FENCE_MONITORED_OBJECT_ACTION_TYPE_ENTER) {
NSLog(@"被监控对象 %@ 进入 客户端地理围栏 %@ ", content.monitoredObject, content.fenceName);
} else if (content.actionType == BTK_FENCE_MONITORED_OBJECT_ACTION_TYPE_EXIT) {
NSLog(@"被监控对象 %@ 离开 客户端地理围栏 %@ ", content.monitoredObject, content.fenceName);
}
}
}
偏好设置

iOS鹰眼轨迹SDK支持开发者对SDK的某些行为偏好进行自定义设置。主要分为定位选项设置、采集周期与上传周期设置、缓存容量设置3个方面。

定位选项设置

iOS鹰眼轨迹SDK使用iOS系统定位服务(CoreLocation),开发者可以通过 BTKAction 类中

-(void)setLocationAttributeWithActivityType:(CLActivityType)activityType
desiredAccuracy:(CLLocationAccuracy)desiredAccuracy
distanceFilter:(CLLocationDistance)distanceFilter;

方法设置CoreLocation中定位的活动类型、定位精度以及触发定位的距离阈值。该方法中的3个参数,将会透传给CoreLocation的LocationManager,3个参数的值请参考苹果官方文档中的用法,根据开发者自己的使用场景进行设置。

采集周期与上传周期设置

iOS鹰眼轨迹SDK默认的采集周期为5秒,上传周期为30秒,即SDK会每隔5秒采集一次当前设备的位置信息,每隔30秒将该周期内的若干个位置信息打包、压缩、加密后传输至鹰眼服务端。

SDK支持开发者通过 BTKAction 类中的 -(void)changeGatherAndPackIntervals:(NSUInteger)gatherInterval packInterval:(NSUInteger)packInterval delegate:(id <BTKTraceDelegate>)delegate; 方法自定义采集周期和上传周期。设置结果会通过 -(void)onChangeGatherAndPackIntervals:(BTKChangeIntervalErrorCode)error 方法回调给开发者。通过changeGatherAndPackIntervals方法设置采集和打包周期时,要求采集周期和上传周期的值域均为[2, 300],且上传周期必须是采集周期的整数倍,否则回调的结果中error参数的值为 BTK_CHANGE_INTERVAL_PARAM_ERROR,代表参数错误。

需要注意的是,该值一经设置,永久有效。即使是重新开启轨迹服务,也会按照上一次设置过的采集周期和上传周期进行采集和上传,SDK默认的采集周期和上传周期不再有效。如果想更改周期,再次调用此方法即可。该方法在开启轨迹服务之前和之后都可以调用。

采集周期一定是准确的,而上传周期只在网络畅通的时候才有意义。网络畅通的情况下,按照5秒采集30秒上传的默认值,查询历史轨迹时会发现,各轨迹点的loctime间隔为采集周期,而每6个连续的轨迹点的create_time是相同的,代表这6个点是同时上传至服务端的。而当断网时,SDK会自动缓存轨迹,等网络恢复后再批量上传至服务端。这种情况下,当查询历史轨迹时会发现,各轨迹点的loctime间隔仍然为采集周期,但create_time则没有什么规律了。但SDK会保证同一个entity终端的轨迹点,loctime较晚的点不会在loctime较早的点之前上传,以确保正确触发服务端地理围栏报警。

以下代码片段表示,将SDK默认的5秒采集一次位置信息、30秒上传一次位置信息,改为自定义的2秒采集一次位置信息、10秒上传一次位置信息。直到下次调用此方法,重新自定义采集周期和上传周期,SDK将一直使用本次自定义的值,即使停止轨迹服务后,重新开启轨迹服务也不受影响。

[BTKAction sharedInstance] changeGatherAndPackIntervals:2 packInterval:10 delegate:self];

缓存容量设置

iOS鹰眼轨迹SDK支持开发者自定义SDK缓存所占磁盘空间的最大值。开发者可以通过 BTKAction 类的 -(void)setCacheMaxSize:(NSUInteger)size delegate:(id <BTKTraceDelegate>)delegate; 方法进行设置。关于此方法的行为有以下几点说明:

1.如果设置了该阈值,当SDK缓存的数据占用磁盘超过该阈值时,将删除最早的缓存轨迹,直到满足该条件。

2.SDK默认情况下缓存占用空间没有限制。

3.如果对于缓存占用空间没有非常强烈的要求,建议不要调用此方法,否则将会导致缓存轨迹数据被丢弃等情况,且数据无法找回。

阈值一经设置,永久有效。如果想取消限制,只有再次设置一个非常大的值才行。 以下代码片段表示,设置客户端缓存占用磁盘空间的最大值为60MB,缓存轨迹数据占用超过60MB时将清空最早的缓存轨迹,直到占用空间满足要求。

[[BTKAction sharedInstance] setCacheMaxSize:60 delegate:self];
自行上传轨迹点

iOS鹰眼轨迹SDK除了可以自动采集并上传轨迹信息外,还支持开发者通过调用接口主动上传轨迹点。比如在两个采集周期之间,上传某个轨迹点作为补充;或者上传非当前登陆的entity的其他终端的轨迹点等使用场景。自定义轨迹点有如下几点说明:

自行上传的轨迹点除了可以上传位置坐标以及速度、方向、海拔高度、定位精度等系统预定义的track属性字段外,同样支持开发者自定义的track属性字段的上传,类似通过 BTKTraceDelegate 协议中的 -(NSDictionary *)onGetCustomData; 方法设置每个轨迹点的附加数据。

自行上传的轨迹点和鹰眼SDK主动采集上传的轨迹点存在以下异同:

① 自行上传的轨迹点上传至服务端之后,和SDK自动采集上传的点没有区别。都会触发服务端地理围栏的计算、查询实时位置和轨迹时,也会返回。但自行上传的轨迹点的上传不会参与客户端地理围栏的计算,也就不会触发客户端地理围栏报警。

② 自行上传的轨迹点的上传依赖网络连通,仅在网络连通时可上传成功,鹰眼SDK也不会缓存上传失败的轨迹点。

示例一:上传某个entity的单个轨迹点

通过 -(void)addCustomPointWith:(BTKAddCustomTrackPointRequest *)request delegate:(id<BTKTrackDelegate>)delegate; 方法,上传单个的自定义轨迹点;

以下代码片段表示,100000这个service下,已经通过轨迹管理台创建了3个叫做”someIntColumn”、 “someDoubleColumn”、 “someStringColumn” 的自定义track属性。名称为 “entityA” 的终端,在10秒钟之前,出现在了东经111.123456度,北纬44.654321度的位置,当时它的 “someIntColumn”属性的值为50,someDoubleColumn属性的值为44.55,someStringColumn属性的值为“aaa”,且方向为北偏东11度,海拔高度58米,定位精度为3米,速度为68米/秒。

// 设置轨迹点的坐标
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(44.654321, 111.123456);
// 设置轨迹点的定位时间戳
NSUInteger timestamp = [[NSDate date] timeIntervalSince1970] - 10;
// 设置轨迹点的自定义track属性字段的值
NSMutableDictionary *customData = [NSMutableDictionary dictionaryWithCapacity:3];
customData[@"someIntColumn"] = @50;
customData[@"someDoubleColumn"] = @44.55;
customData[@"someStringColumn"] = @"aaa";
// 构造自定义轨迹点
BTKCustomTrackPoint *point = [[BTKCustomTrackPoint alloc] initWithCoordinate:coordinate coordType:BTK_COORDTYPE_BD09LL loctime:timestamp direction:11 height:58 radius:3 speed:68 customData:customData entityName:@"entityA"];
// 使用自定义轨迹点构造请求对象
BTKAddCustomTrackPointRequest *request = [[BTKAddCustomTrackPointRequest alloc] initWithCustomTrackPoint:point serviceID:100000 tag:444];
// 发起上传请求
[[BTKTrackAction sharedInstance] addCustomPointWith:request delegate:self];
示例二:批量上传多个entity的多个轨迹点

通过 -(void)batchAddCustomPointWith:(BTKBatchAddCustomTrackPointRequest *)request delegate:

(id<BTKTrackDelegate>)delegate; 方法,批量上传若干个开发者自定义轨迹点,这些轨迹点可以属于不同的终端实体。

以下代码片段表示,一次性上传2个自定义轨迹点,分别属于entityA和entityB,每个轨迹点的设置与上面上传单个轨迹点时相同。

// 第一个轨迹点point1
CLLocationCoordinate2D coordinate1 = CLLocationCoordinate2DMake(44.44, 111.11);
NSUInteger timestamp1 = [[NSDate date] timeIntervalSince1970] - 10;
NSMutableDictionary *customData1 = [NSMutableDictionary dictionaryWithCapacity:3];
customData1[@"someIntColumn"] = @50;
customData1[@"someDoubleColumn"] = @44.55;
customData1[@"someStringColumn"] = @"aaa";
BTKCustomTrackPoint *point1 = [[BTKCustomTrackPoint alloc] initWithCoordinate:coordinate1 coordType:BTK_COORDTYPE_BD09LL loctime:timestamp1 direction:11 height:11 radius:11 speed:11 customData:customData1 entityName:@"entityA"];
// 第二个轨迹点point2
CLLocationCoordinate2D coordinate2 = CLLocationCoordinate2DMake(55.55, 122.22);
NSUInteger timestamp2 = [[NSDate date] timeIntervalSince1970] - 20;
NSMutableDictionary *customData2 = [NSMutableDictionary dictionaryWithCapacity:3];
customData2[@"someIntColumn"] = @50;
customData2[@"someDoubleColumn"] = @44.55;
customData2[@"someStringColumn"] = @"aaa";
BTKCustomTrackPoint *point2 = [[BTKCustomTrackPoint alloc] initWithCoordinate:coordinate2 coordType:BTK_COORDTYPE_BD09LL loctime:timestamp2 direction:22 height:22 radius:22 speed:22 customData:customData2 entityName:@"entityB"];
// 构造需要上传的多个轨迹点
NSMutableArray *points = [NSMutableArray arrayWithCapacity:2];
[points addObject:point1];
[points addObject:point2];
// 构造请求对象
BTKBatchAddCustomTrackPointRequest *request = [[BTKBatchAddCustomTrackPointRequest alloc] initWithCustomTrackPoints:points serviceID:100000 tag:444];
// 发起请求
[[BTKTrackAction sharedInstance] batchAddCustomPointWith:request delegate:self];

上一篇

隐私合规接口说明

下一篇

缓存轨迹处理

本篇文章对您是否有帮助?