开发技巧

工程配置要点

使用鹰眼SDK的APP工程中,有几个配置项需要我们重点关注,以下分别对它们进行解释:

1. Build Settings -> BuildOptions -> Embedded Content Contains Swift Code 这个选项用来告诉编译器你的工程中是否包含了swift的代码,由于鹰眼SDK使用Swift语言编写,所以需要将此项的值设置为Yes,这一项在Xcode中默认设置为No,如果没有设置的话,会报dyld: Library not loaded: @rpath/libswiftCore.dylib 这个错误。


2. Build Settings -> BuildOptions -> Enable Bitcode 这个选项用来告诉编译器你的工程是否支持BitCode。BitCode可以认为是一种中间形式的代码,如果你的APP支持BitCode,那么在你将你的程序提交至App Store后,苹果可以随时通过编译连接BitCode来优化你的程序,例如减小最终APP的大小等,而不需要你重新上传一遍应用程序。如果你的APP中EnableBitcode选项设置为Yes,而你所使用的第三库中有任意一个不支持Bitcode的话,会得到xxx does not contain bitcode的编译错误。鹰眼SDK目前不支持Bitcode, Xcode中此选项默认设置为Yes,所以需要您将此选项设置为No,才能正常使用。


3. Build Settings ->Linking -> Other Linker Flags 这个选项用来配置Xcode的链接器的参数,有三个常用的参数,分别是-Objc, -all_load 以及 –force_load,如果您将此选项设置为了-all_load,链接器会把之前编译生成的所有目标文件一起进行链接,如果您的APP中使用了多个第三方库,第三方库中又使用了相同的开源库等,又没有进行处理,那么在编译之后可能会生成相同的目标文件,进而会报 ld:duplicate symbol错误。鹰眼SDK中已经对类名和全局变量等加了前缀处理,绝大多数情况下不会出现duplicate symbol链接错误,如果出现错误,请将这个配置项的值改为-force_load 加上需要全部加载的库的路径,这样会保证链接器会包括这个库的全部目标文件,而其他的库如果有重复的目标文件,则不再进行加载。


4. General -> DeploymentInfo -> Deployment Target 选项需要设置为8.0以上。由于鹰眼SDK使用Swift语言编写,目前APP STORE规定含有swift代码的APP支持的最低iOS版本为iOS8.0,否则无法上架到APP STORE,所以鹰眼SDK中的DeploymentTarget已经设置为8.0,使用鹰眼SDK的APP的这个选项只能设置为8.0以上。(注:截止2016年1月11日,根据APP STORE的官方统计数据,已有93%的iOS设备的版本在iOS8.0以上。)


5. 由于鹰眼SDK需要在后台使用定位功能,在您APP的info.plist文件中,需要加上以下配置

<key>NSLocationAlwaysUsageDescription</key>
<string>需要后台定位</string>
<key>UIBackgroundModes</key>
<array>
       <string>location</string>
</array>

由于iOS9中对HTTP请求的限制,请加上以下配置

<key>NSAppTransportSecurity</key>
<dict>
       <key>NSAllowsArbitraryLoads</key>
       <true/>
</dict>

SDK使用要点

1. 自定义字段的上传

鹰眼SDK除了采集轨迹数据外,对每一个轨迹点,可以同时上传用户自定义的数据。在ApplicationServiceDelegate 协议中的trackAttr()方法在每个采集周期都会被回调一次。开发者实现这个方法时,需要返回一个字典,键是自定义字段的名称,值是自定义字段的值。该方法为可选方法,如果没有需要上传的自定义字段,就不需要实现这个方法。另外,需要注意的是,在此之前,开发者需要调用HTTP接口track/addcolumn等先添加您想上传的自定义字段,才会起作用。


2. 采集周期和打包周期的设置

鹰眼SDK可以由开发者自己设置轨迹的采集和打包周期,默认的采集周期为5秒,打包周期为30秒。采集周期的值域为[2,60],打包周期的值域为[2,60],且打包周期必须大于采集周期且是采集周期的整数倍。比如您可以通过setInterval方法将采集周期设置为2秒,打包周围设置为10秒等。需要注意的是,采集周期设置地越小,采集的轨迹点越多,上传时也就会消耗更多的流量。目前鹰眼iOS SDK 2.0.0版只支持实例化BTRACE类之后,在startTrace之前先设置采集和打包周期,如果在使用过程中,需要更改采集和打包周期,则需要先stopTrace后,再重新设置并重新startTrace。2.0.1Beta版已经支持在运行期间动态设置采集和打包周期,请见论坛置顶帖下载。


3. 定位相关属性的设置

可以通过setAttributeOfLocation(activityType:Int, desiredAccuracy: Int, distanceFilter: Double) 接口设置定位相关的属性,三个参数的含义分别如下:


activityType:代表定位设备的活动类型,在BTRACEActivityTypeOfLocation中定义了4种类型,该参数主要用来控制设备定位的频率,以节省电量。


desiredAccuracy:代表需要的定位精度,请根据您应用的场景选择合适的定位精度。精度越高,对电量的消耗越大。在BTRACEDesiredAccuracyOfLocation类中定义了6种精度类型。


distanceFilter:代表触发定位的距离阈值,该值为非负数,单位为米,0代表尽可能触发定位,这样会带来较高的电量消耗,比如设置为100米,代表当你移动了100米后才更新一次你的位置。需要根据您的使用场景进行权衡,比如您的应用场景是步行,采集频率设置为2秒采集一次。那么有可能连续的几十次采集得到的都是相同的位置,直到你的位置更新了100左右后,才会重新触发定位,你的位置才会更新。如果您的应用场景是驾车的话,那么可能只有一两个采集得到的是相同的位置,这样的场景下设置2秒的采集周期,100米的距离阈值,automotive的activityType就比较合适了。


接口使用要点

1. 鹰眼iOS SDK中提供了4个方面的接口,所有的接口都在BTRACEAction中,所有接口都为异步方式,分为ApplicationEntityDelegate 、ApplicationFenceDelegate、ApplicationServiceDelegate 以及ApplicationTrackDelegate四个协议,遵守相关协议的类中,相应地方法就会被回调到。


2. 参数类型为NSData的方法都是查询类请求的回调方法,需要按照JSON解析,OC语言可以使用DEMO中的JSONKit库进行解析,由于该库很久没有人维护,不支持ARC模式,如果有需要可以使用我们维护的版本,您可以在鹰眼SDK的Objective-C版本的DEMO中找到JSONKit.h和JSONKit.m文件。强调一下,这两个文件版权不归百度鹰眼所有,遵循BSD协议,JSONKit库的原作者为JohnEngelhart,具体的版权规定请看这两个文件上方的版权注释。另外,在您导入这两个文件之后,您还需要在您的Target->Build Phases->Compile Sources选项中找到JSONKit.m,增加-fno-objc-arc 参数。


3. ApplicationServiceDelegate中的几个回调方法比较特殊,在此做出说明: onStartTrace和onStopTrace分别为开启轨迹服务和结束轨迹服务的回调方法,errNo代表状态码 errMsg代表消息内容。

onPushTrace为推送的回调方法,当您为监控对象设置了地理围栏,且该对象触发了报警时,该方法会被回调。

onChangeGatherAndPackIntervalsAfterStartTrace为动态设置采集和打包周期的回调方法,该回调方法对应的方法是changeGatherAndPackIntervalsAfterStartTrace,该方法需要在startTrace之后,服务已经运行的情况下调用,如果是在服务开启之前设置采集和打包周期,请使用BTRACE类中得setInterval方法。

比较特殊的是trackAttr()方法,该回调方法的使用已在上篇中说明。

代码可以写成下面这样:

- (NSDictionary* __nullable)trackAttr {
   NSMutableDictionary *glossary = [NSMutableDictionary dictionary];
    [glossarysetObject: @"col1" forKey: @"v1"];
    [glossarysetObject: @"col2" forKey: @"v2"];
    returnglossary;
}

这样实现之前,开发者需要调用webapi的track/addcolumn接口为track添加col1和col2这两个属性字段(此接口的链接为http://lbsyun.baidu.com/index.php?title=yingyan/api/track#addcolumn.E2.80.94.E2.80.94.E6.B7.BB.E5.8A.A0track.E7.9A.84.E5.B1.9E.E6.80.A7.E5.AD.97.E6.AE.B5),在已有这两个字段的前提下,实现这个方法才能将附加数据回传。以上实现的意思是,在本次的位置数据中附加两个字段col1和col2它们的值分别为v1和v2。在每个采集周期,该方法都会被回调一次,假如您想将发动机转速作为附加数据上传,可以这样:

- (NSDictionary* __nullable)trackAttr {
    return getRotationSpeed();
}
 
- (NSDictionary* )getRotationSpeed {
    NSMutableDictionary *dic =[NSMutableDictionary dictionary];
    extern NSString* speed;
    [dicsetObject: @"speed" forKey: speed];
    return dic;
}
//该函数是开发者自己实现的发动机转速的回调函数
(void)onRotationSpeedChange:(NSData*)data{
          extern NSString* speed;
          speed= [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

4. 在使用所有接口之前,第一步一定是先实例化BTRACE这个类,例如这样: BTRACE* traceInstance =[[BTRACE alloc] initWithAk: AK mcode: MCODE serviceId: serviceId entityName:entityName operationMode: 2]; 其中有两个参数需要特别说明,entityName即需要被追踪的实体的唯一标识符,这个entityName可以是之前通过webapi的HTTP接口 entity/add 添加过的(链接为http://lbsyun.baidu.com/index.php?title=yingyan/api/entity),也可以是一个新的entityName,如果是已有的entityName,则初始化BTRACE且startTrace后,所采集上传的位置数据将算在该entityName名下;如果是一个新的entityName,则初始化BTRACE且startTrace后,后台将会自动添加一个entity。第二个需要说明的参数是operationMode,该参数代表你所要创建的轨迹服务的类型,0代表不建立长连接,只调用HTTP的查询类接口,这是将无法追踪上传位置,无法接受推送服务,1代表建立长连接但不采集数据,此时将只能接受推送服务,围栏报警等,2代表建立长连接且采集数据,使用此值初始化BTRACE且startTrace后,将会自动采集并上传位置,且可以接受推送报警等。假如有一种场景是家长监控小孩的位置,那么小孩的APP上operationMode应该设置为2,采集并上传位置,家长的APP上operationMode可以设置为1,不采集自己的位置,只接收小孩的围栏报警或查询小孩的实时和历史轨迹等场景。需要说明的是,当operationMode为1时,由于SDK不会访问您的位置数据,那么SDK将无法继续后台运行,这时如果要使APP退到后台之后,不被系统挂起,需要APP中做相应地操作来保持APP不被挂起,否则在后台时无法接收到围栏报警通知。

常见报错汇总及处理方法

1. Reason: Incompatible library version: BaiduTraceSDK requires version 1.0.0 or later, but libswiftCore.dylib provides version 0.0.0


该问题是由于Xcode版本和SDK不匹配导致的。请使用最新版的Xcode(7.3)以及最新版的SDK(2.0.3)即可解决。


2. embedded content contains swift code设置YES后还是报Reason: image not found的错误


1)把无关证书删除,重新在本机生成证书,于描述文件

2)使用xcode自动生成app ids和描述文件的人注意了,不要用xocde自动生成,自己生成就好了

3)按照正常步骤导入framework配置路径即可,embedded content contains swift code改为YES

4)运行


3. no matching architecture in universal wrapper错误


将emdded content contain swift code 改成yes

将enable bitcode 改成no