全部产品
云市场

iOS接入

更新时间:2019-09-25 10:26:43

一. ACCS SDK 初始化

  • 指定仓库:
  1. source 'git@gitlab-ce.emas-poc.com:EMAS-iOS/emas-specs.git'
  • 添加依赖:
  1. pod 'TBAccsSDK', '10.0.7'
  2. pod 'NetworkSDK', '10.0.4.4'
  3. pod 'tnet', '10.3.0'
  • 初始化设置:
  • 引入头文件
  1. #import <TBAccsSDK/TBAccsManager.h>
  • 作为基础中间件请使用方尽量早的初始化TBAccsSDK,建议在程序启动后AppDelegate中的didFinishLaunchingWithOptions回调中就完成初始化的工作:
  1. // 初始化参数
  2. TBAccsConfiguration *config = [[TBAccsConfiguration alloc] initWithHost:@"accs.domain.com"];
  3. // App唯一标识,必填
  4. config.appkey = @"12345";
  5. // 请求加密加签使用,必填
  6. config.appsecret = @"abcdefghijklmnopqrst";
  7. // 连接指定IP
  8. config.defaultIP = @"10.10.10.10";
  9. // 连接指定端口
  10. config.defaultPort = 443;
  11. // 设置EMAS专用公钥
  12. config.slightSSLPublickeyIndex = ACCS_PUBKEY_PSEQ_EMAS;
  13. // 根据config构建ACCS实例,并启动
  14. TBAccsManager *accsManager = [TBAccsManager createAccsWithConfiguration:config];
  15. [accsManager startAccs];
  • 若不指定IP+Port, 亦可设置通过Local DNS的方式建立连接:
  1. // 初始化参数
  2. TBAccsConfiguration *config = [[TBAccsConfiguration alloc] initWithHost:@"accs.domain.com"];
  3. // App唯一标识,必填
  4. config.appkey = @“12345”;
  5. // 请求加密加签使用,必填
  6. config.appsecret = @“abcdefghijklmnopqrst”;
  7. // 指定使用local dns
  8. config.supportLocalDnsWhenNoPolicy = YES;
  9. // 设置EMAS专用公钥
  10. config.slightSSLPublickeyIndex = ACCS_PUBKEY_PSEQ_EMAS;
  11. // 根据config构建ACCS实例,并启动
  12. TBAccsManager *accsManager = [TBAccsManager createAccsWithConfiguration:config];
  13. [accsManager startAccs];
  • 相关概念解释:

    1. 上行

      客户端向服务单主动发送数据,我们称之为上行数据

      • REQ/RES模式

      客户端每次向服务端请求后,服务端响应一个数据应答包,这种方式与传统的http请求类似。

      • Data模式:

      客户端向服务端发送数据,没有应答数据包,只有ACK,且业务层无须接收ACK。

      • ACK:

      accs的每条下行数据都会返回服务端ack, ack可以透传给业务, 业务可以选择接收或不接收。

    2. 下行

      服务端主动向客户端推送数据,我们称之为下行数据。

二. SDK 接口调用

2.1 Bind App

  • app启动后,马上调用此接口。appleDeviceToken参数可以传入空。此接口可以被多次调用。
  1. [_accsManager bindAppWithAppleToken: appleDeviceToken
  2. callBack:^(NSError *error, NSDictionary *resultsDict) {
  3. if (error) {
  4. AccsLog(@"\n\n绑定App出错了 %@\n\n", error);
  5. }
  6. else {
  7. AccsLog(@"\n\n绑定App成功了\n\n");
  8. }
  9. }];

只有绑定APP成功,ACCS 实例才能正常接收下行消息,否则只能发送上行消息。

  • BindApp 在端上有6小时状态缓存,也即在6小时后,真实的BindApp请求只会向服务端发送一次, 若需要强制发送BindApp请求至服务端:
  1. [_accsManager bindAppWithAppleToken: appleDeviceToken
  2. force: YES
  3. callBack:^(NSError *error, NSDictionary *resultsDict) {
  4. if (error) {
  5. AccsLog(@"\n\n绑定App出错了 %@\n\n", error);
  6. }
  7. else {
  8. AccsLog(@"\n\n绑定App成功了\n\n");
  9. }
  10. }];

2.2 绑定/解绑用户

绑定用户动作在ACCS中不是必须的,ACCS设备检索是依赖deviceid (就是utdid)。端上通过bind user之后,业务端可以使用业务自己的userid来检索设备, 实现用户维度运维发送消息。注意同一个userId最多只能绑定20个设备,超出该限制后,绑定会失败。

  1. [_accsManager bindUserWithUserId: _userId.text
  2. callBack:^(NSError *error, NSDictionary *resultsDict) {
  3. if (error) {
  4. AccsLog(@"\n\n绑定用户出错了 %@\n\n", error);
  5. }
  6. else {
  7. AccsLog(@"\n\n绑定用户成功了\n\n");
  8. }
  9. }];
  10. [_accsManager unbindUserWithUserId:_userId.text callBack:^(NSError *error, NSDictionary *resultsDict) {
  11. if (error) {
  12. AccsLog(@"解绑用户出错: %@", error);
  13. } else {
  14. AccsLog(@"解绑用户成功");
  15. }
  16. }];

2.3 发送上行数据

参数说明:

  • data: 需要发送的数据
  • serviceId: 目标服务;
  • userId: 发送用户标识,一般为nil
  • otherParameters: 没有使用,填nil
  • callBack: 发送结果回调
  1. [_accsManager sendRequestWithData: [_message.text dataUsingEncoding: NSUTF8StringEncoding]
  2. serviceId: @“your_service_id
  3. userId: @"your_user_id"
  4. otherParameters: nil
  5. callBack:^(NSError *error, NSDictionary *resultsDict) {
  6. if (error) {
  7. AccsLog(@"发送数据失败sendRequest: %@", error);
  8. }
  9. else{
  10. AccsLog(@"发送数据成功sendRequest");
  11. }
  12. }];

2.4 订阅下行消息

订阅下行消息通过API: Bind Service 来完成:

参数说明:

  • serviceId: 需要监听下行数据的服务id, 需要找服务端同学来获取;(如果服务端尚未完成接入,在测试阶段可以使用测试用的serviceId,即emas-test
  • callback: 函数调用结果回调,error==nil 时表示成功,resultsDict表示绑定时ACCS后端返回的response;
  • receviceDataBlock: 即下行数据监听回调,若绑定成功后,目标服务有下行数据,将会在改block中接收具体下行数据
  1. [_accsManager bindServiceWithServiceId: _serviceId.text
  2. callBack:^(NSError *error, NSDictionary *resultsDict) {
  3. if (error){
  4. AccsLog(@"绑定Service出错了");
  5. }
  6. else{
  7. AccsLog(@"绑定Service成功了");
  8. }
  9. }
  10. receviceDataBlock:^(NSError *error, NSDictionary *resultsDict){
  11. if (error){
  12. AccsLog(@"接收 Accs 数据出错 %@", error.description);
  13. }
  14. else{
  15. AccsLog(@"接收 Accs 数据成功 %@", resultsDict[@"jsonString"]);
  16. }
  17. }];

返回的数据在 resultDict 中,解析如下:

  1. // message id
  2. NSString *dataId = [resultsDict objectForKey:@"dataId"];
  3. // from which service
  4. NSString *serviceId = [resultsDict objectForKey:@"serviceId"];
  5. // message payload, binary data
  6. NSData *payload = [resultsDict objectForKey:@"resultData"];
  7. // 例如业务端发送payload 是一个字符串,则解析成字串
  8. NSString *text = [[NSString alloc] initWithData:payload encoding:NSUTF8StringEncoding];

2.5 注册离线消息监听

“离线消息”概念:

当ACCS连接在线时,服务端通过ACCS推送下来的消息称之为“在线消息”;当ACCS连接离线时,服务端把需要的下行消息缓存起来,当设备再次上线时,再推下去,这些消息称之为“离线消息”

因连接一旦建立成功,服务端即会立即推送缓存的离线消息,因为业务使用SDK时的时序不可控,有可能数据到达SDK时,业务尚未bind service, 导致消息被丢弃。为解决此问题,业务可在AccsReceiverTable.plist中注册下行消息接收handler, ACCS在初始化时,通过反射创建注册的handler, 把收到的消息投递出去,避免业务bind service过晚而导致的消息丢失。注意:大小写敏感!

AccsReceiverTable.plist文件路径无特殊需求,添加到主客工程中即可。

注册格式如下:

  1. {
  2. "im": {
  3. "class": "TBIMAccsAdapter"
  4. }
  5. }

im表示自己申请的serviceID,class表示需要实现以下协议的类,accs会根据类名和协议方法动态调用此类,其中 TBIMAccsAdapter 需要实现以下接口:

  1. @protocol TBAccsCallbackProtocol <NSObject>
  2. @required
  3. + (TBAccsManagerResponseBlock)callBack;
  4. + (NSString *)serviceID;
  5. @optional
  6. + (NSString *)accsHost; // ACCS Host, 可以不写
  7. @end

三. 调试日志

  • TBAccsSDK 日志

在接入调试的时候,若出现异常&错误不便排查,可以打开SDK日志,通过日志排查问题原因:

  1. // 先声明日志开关函数
  2. void tbAccsSDKSwitchLog(BOOL logCtr);
  3. // 打开日志
  4. tbAccsSDKSwitchLog(YES);
  • NetworkSDK 日志

因为TBAccsSDK中连接的建连、保活等基础逻辑是在网络库中实现,所以有时我们需要进一步查看网络库的日志:

  1. #import "NWLog.h"
  2. [NWLog setLogLevel:NW_LOG_DEBUG];

四. 错误码

所有上行接口的回调参数中的NSError* 若为nil, 则表示无错误;若非空,其解释如下:

错误码 解释 场景场景
7001 请求超时 timeout 设置过短,或服务端阻塞
7002 请求构建失败 依赖无线保镖时,appkey 在安全文件中无配置
7003 无通道 连接断开
7004 上行帧发送错误 发送失败
7005 ACCS flag错误 下行数据服务端报文格式错误
7006 无网络
7007 多次重试无响应 对应ACCS服务端宕机
70019 上行数据为空
70020 服务端低级别限流 客户端在一段时间,不发起任何请求
70021 服务端高级别限流 客户端会每隔几毫秒发一个请求,给服务端减轻压力
70022 防刷限流 客户端QPS过高,用户需要输入验证码,客户端才可以继续发请求