页面树结构
转至元数据结尾
转至元数据起始

前置准备

1 下载XlinkSDK

      请点击这里下载XlinkSDK:iOS SDK 下载及更新说明

2 导入XlinkSDK

  • 解压缩你下载的Xlink iOS SDK压缩包,把解压得到的“XLinkSDK”文件夹拖入到您的工程项目中。

  • 配置头文件搜索路径:进入Xcode工程属性页面,进入BuildSettings标签,找到HeaderSearchPaths选项,将libxlink/include目录加入SearchPaths;

  • 配置库文件搜索路径:进入Xcode工程属性页面,进入BuildSettings标签,找到LibrarySearchPaths选项,将libxlink/lib下针对模拟器和实体机加载的库的路径配置到SearhPaths中。

3 添加必要系统库

  • 进入Build Phases ,点击打开“Link Binary With Library”,添加“libz.tbd”。

4 其他配置

  • 把工程中其中一个.m文件修改为.mm后缀。例如把"AppDelegate.m""AppDelegate.mm"。
  • 添加Other Linker Flags -ObjC

基本使用流程

一般情况下,云智易SDK(以下简称SDK)的使用过程大致如下图所示:

      配置/初始化SDK
           +     +
           |     |
        +--+     v
        |       扫描设备 +----->选择并订阅新设备
        |                             +
        |                             |
        | <---------------------------+
        v
     连接设备
        +---------------------+-----------------+
        |                     |                 |
        |                     |                 |
        v                     v                 v
   设置/查询数据端点    接收设备状态回调    接收云端推送


1 启动SDK/关闭SDK

程序运行前要初始化。配置SDK,调用start()后生效。

XLinkConfig *config = [[XLinkConfig alloc]init];
config.apiServer = @"https://api2.xlink.cn:443";
config.cloudServer = @"mqtt.xlink.cn";
//使用ssl
config.cloudServerPort = @"1884";
config.enableSSL = YES;

配置SDK后,调用start()后生效。


[[XLinkSDK share]setXlinkConfig:config];
[[XLinkSDK share]start];

或者直接使用下面一句直接开始


[[XLinkSDK share]startWithConfig:config];

配置选项列表如下所示:

配置名称含义默认值
corpId企业IDnil
cloudServer设置云端服务器IPmqtt.xlink.cn
cloudServerPort设置云端服务器端口1883
apiServer设置HTTP API服务器https://api2.xlink.cn:443
enableSSL是否使用SSLNO
SSLCertificateFilePath设置SSL证书路径nil
setDebug(Boolean)是否打印SDK日志NO

对于一般开发者来说,使用默认值即可。


开始后需要分别设置设置SDK的云端连接状态、数据传输、设备连接状态的代理,以监测这些状态或者数据的变化。

1.1设置云端连接状态回调的代理:


[XLinkSDK share].cloudDelegate = self;

云端回调方法:

// 当SDK与云平台连上/断开的时候,会回调这个方法。
-(void)onCloudStateChangedWithCloudConnectionState:(CloudConnectionState)state{
}
// 当SDK连接上云端,并接收到云端推送时,会回调这个方法。
-(void)onReceiveEventNotify:(EventNotify *)eventNotify{
}


1.2 设置设备连接状态回调的代理:

[XLinkSDK share].deviceStateDelegate = self;

设备连接状态回调方法

// 受SDK管理的设备状态发生改变时
-(void)onDeviceStateChanged:(XDevice *)xDevice withDeviceState:(XDeviceState)state{
}

// 设备属性(设备名称)或者设备状态发生改变时,还有设备订阅关系变化的时候会回调这个方法。
- (void)onDeviceChanged:(XDevice *)xDevice withEvent:(XDeviceEvent)event{
}

1.3 设置设备接收到数据回调的代理:

//接收数据端点变化的回调
[XLinkSDK share].dataDelegate = self;
 // 受SDK管理的设备接收到DataPoint更新的时候
 -(void)onDataPointUpdateWithDevice:(XDevice *)xDevice withList:(NSArray <XLinkDataPoint *>*)list{
}

1.4 用户授权状态变化回调的代理:

// 用户授权状态变化回调的代理
[XLinkSDK share].userDelegate = self;
//当帐号信息被正确设置,而且用户被下线(被踢或者手动退出)的时候,会回调这个方法。
- (void)onUserLogout:(LogoutReason)reason{
}


配置好SDK后,在需要时,可启动SDK。

// 启动SDK
[[XLinkSDK share] start];

不使用SDK时,可调用stop()

// 停止SDK, 断开云端连接,回收资源
[[XLinkSDK share] stop];

当App退出登录(授权失败、用户主动退出或其他原因需要重新授权的情况,一般在onUserLogout回调中使用)时,可调用logoutAndStop()

// 停止SDK, 断开云端连接,回收资源,清除授权信息。
[[XLinkSDK share] logoutAndStop];
启动SDK后,若要使用云端服务,应进行用户授权:
XLinkUserAuthorizeTask *task = [XLinkUserAuthorizeTask userAuthorizeTaskWithAccount:mAccount withPassword:mPassword withCropId:mCorpId withCompleteBlock:^(id result, NSError *err) {
        if (err) {// 登录失败

        }else {// 登录成功,在result中含有授权信息,SDK内部自动进行云端连接

        }
}];
[task start];

如使用第三方登陆,请调用XLinkThirdPartyAuthorizeTask:

XLinkThirdPartyAuthorizeTask *task = [XLinkThirdPartyAuthorizeTask thirdPartyUserAuthorizeTaskWithSource:XLinkUserSourceTypeWeibo withOpenId:mOpenid withAccessToken:mAccessToken withNickName:mNickName withCropId:mCorpid withCompleteBlock:^(id result, NSError *err) {
        if (err) {// 登录失败

        }else {// 登录成功,在result中含有授权信息,SDK内部自动进行云端连接

        }
}];
[task start];

由于SDK内部需要授权信息,请使用SDK提供的授权接口进行授权,不要自行通过Restful进行用户授权。

2.添加设备

一般来说,添加设备的流程如下所示:

重置设备 ----> 设备配网 ----> 搜索同一局域网下的云智易设备 ----> 添加设备

下面对SDK相关的步骤进行描述。

2.1 扫描设备

扫面设备要求设备与SDK处于同一局域网内。首先新建扫描设备任务:

//新建扫描设备任务
XLinkScanDeviceTask *scanTask = [XLinkScanDeviceTask scanDeviceTaskWithProductIds:@[@"123456789",@"987654321"] withTimeOut:90 withGotDeviceBlock:^(XDevice *device) {
    //扫描到设备回调,同一设备仅会回调一次
} withCompleteBlock:^(XLinkErrorCode code) {
    if (code == 0) {//任务执行成功
    }else{//任务执行失败
    }
}];

//执行扫描设备
[[XLinkSDK share] startTask:scanTask];

2.2 添加设备

对于一般开发者来说,添加设备的代码如下所示:


//新建添加设备任务
XLinkAddDeviceTask *addDeviceTask = [XLinkAddDeviceTask addDeviceTaskWithDevice:mDevice withTimeOut:10 withCompleteBlock:^(XLinkErrorCode code) {
    if (code == 0) {//任务执行成功

    }else{////任务执行失败

    }
}];
//执行添加设备
[[XLinkSDK share] startTask:addDeviceTask];
//停止添加设备
[[XLinkSDK share] stopTask:addDeviceTask];
//或者这样子也可以停止添加任务
[addDeviceTask cancel];

已添加成功的设备,SDK会自动在云端建立当前用户账号与设备的订阅关系,并用于后续的数据更新和同步,具体请参考下文的“同步设备列表”。

3   删除设备

新建删除设备任务


//新建删除设备任务
XLinkRemoveDeviceTask *removeDeviceTask = [XLinkRemoveDeviceTask removeDeviceTaskWithDevice:device withTimeOut:10 withCompleteBlock:^(XLinkErrorCode code) {
    if (code == 0) {//任务执行成功
    }else{////任务执行失败
    }
}];
//执行删除设备
[[XLinkSDK share] startTask:removeDeviceTask];
//停止删除设备
[[XLinkSDK share] stopTask:removeDeviceTask];
//或者这样子也可以停止删除任务
[addDeviceTask cancel];

4   同步当前登录用户的设备列表

将云端的设备列表同步到SDK。要求设备和当前用户之间有订阅关系。任务完成后默认自动发起


//新建获取设备列表任务
XLinkSyncDeviceListTask *task = [XLinkSyncDeviceListTask syncDeviceListTaskWithVersion:0 withTimeout:10 withConnectLocal:YES withCompleteBlock:^(NSArray<XDevice *> *devices, XLinkErrorCode code) {
    if (code == 0) {//任务执行成功
    }else{//任务执行失败
    }
}];

//执行获取设备列表任务
[[XLinkSDK share] startTask:task];
//停止获取设备列表任务
[[XLinkSDK share] stopTask:task];
//或者这样子也可以停止获取设备列表任务
[task cancel]

5  连接设备

连接设备流程图

重置设备--->设备配网---->搜索同一局域网的云智易设备--->添加设备

控制设备,或者获取设备信息之前,必须先对设备进行连接。这里是指SDK于设备之间通过内网或者外网进行连接。其中内网采用UDP连接,外网采用TCP连接。

SDK会自动维护设备的连接,即SDK检测到与设备断开连接后,会自动重连。

具体使用方法如下所示:

//新建连接任务
XLinkConnectDeviceTask *connectDeviceTask = [XLinkConnectDeviceTask connectDeviceTaskWithDevice:device withTimeOut:20 withCompleteBlock:^(XLinkErrorCode code) {
    if (errCode == 0) {//任务执行成功
    }else{//任务执行失败
    }
}];

//执行获取设备列表任务
[[XLinkSDK share] startTask:connectDeviceTask];
//停止获取设备列表任务
[[XLinkSDK share] stopTask:connectDeviceTask];
//或者这样子也可以停止获取设备列表任务
[connectDeviceTask cancel];

连接设备成功后,在XLinkSDK的XLinkDeviceStateDelegate中的- (void)onDeviceStateChanged:(XDevice *)xDevice withDeviceState:(XDeviceState)state会被调用。

//订阅设备状态变化
-(void)onDeviceStateChanged:(XDevice *)xDevice withDeviceState:(XDeviceConnectionState)state{
    switch (state) {
        case XDeviceConnectionStateOnline: 
        break;

        case XDeviceConnectionStateOffline:
        break;
        ...
    }
}

断开设备连接。sdk 可以断开与设备的本地连接:

[XLinkSDK share] disconnectLocalWithDevice:mXDevice];

值得注意的是,设备与云端的连接 sdk 无法控制。


6  查询/修改数据端点

SDK支持指定内网/外网发送数据。也可以不指定发送方式,实现完全的透明传输。数据发送的策略有如下几种:

/**
 * 数据发送策略。默认为AUTO
 */
typedef enum : NSUInteger {
    XLinkSendDataPolicyAuto,    /** 自动选择发送数据的通道(内/外网)。选择的依据是当前通道的RTT(Round-Trip Time,往返时延) RTT低的通道会被选中。*/
    XLinkSendDataPolicyLocalOnly,//只尝试从内网发送。
    XLinkSendDataPolicyCloudOnly, //只尝试从外网发送。
    XLinkSendDataPolicyLocalFirst,//尝试从内网发送,失败则尝试外网发送。
    XLinkSendDataPolicyCloudFirst //尝试从外网发送,失败则尝试内网发送。
} XLinkSendDataPolicy

在初始化 XLinkSDK 时可以设置数据发送策略:

[[XLinkSDK share].xlinkConfig setSendDataPolicy:XLinkSendDataPolicyCloudOnly];

查询/修改数据端点之前,必须先对设备进行连接。若要使用云端的数据存储/告警功能,则设备需要连接上云服务器。

//接收数据端点变化的回调
[XLinkSDK share].dataDelegate = self;

 -(void)onDataPointUpdateWithDevice:(XDevice *)xDevice withList:(NSArray <XLinkDataPoint *>*)list{
}

查询所有数据端点的值


 //新建查询所有数据端点的值
XLinkGetDataPointTask *task = [XLinkGetDataPointTask getDataPointTaskWithDevice:mDevice withTimeOut:10.f withGetDataPointTaskCompleteBlock:^(NSArray<XLinkDataPoint *> *result, XLinkErrorCode errCode)  {
    if (errCode == 0) {//任务执行成功
    }else{//任务执行失败
    }
}];
//执行查询数据端点任务
[[XLinkSDK share] startTask:task];
//停止查询数据端点任务
[[XLinkSDK share] stopTask:task];
//或者这样子也可以停止查询数据端点任务
[task cancel];
修改数据端点任务

//新建修改数据端点任务
XLinkSetDataPointTask *task = [XLinkSetDataPointTask setDataPointWithDevice:mDevice withDataPoints:dataPoints withTimeOut:10.f withCompleteBlock:^(XLinkErrorCode code) {
    if (errCode == 0) {//任务执行成功
    }else{//任务执行失败
    }
}];
[[XLinkSDK share] startTask:task];
//停止修改数据端点任务
[[XLinkSDK share] stopTask:task];
//或者这样子也可以停止修改数据端点任务
[task cancel];

订阅某些数据端点的变化


//用户可以指定订阅某些数据端点的变化,传入数据端点的 index 值列表。
XLinkDataPointObserver *dataPointObserver = [XLinkDataPointObserver dataPointObserverWithDevice:device IndexArray:@[@(2),@(3)] withDataPointUpdateBlock:^(XDevice *device, NSArray<DataPoint *> *dataPoints) {

}];
[[XLinkSDK share].dataPointManager addDataPointObserver:dataPointObserver];
//退订某个数据端点的变化
[[XLinkSDK share].dataPointManager removeDataPointObserver:dataPointObserver];

7  接收服务器推送

当SDK使用了云端功能,并连接到云端时,SDK可以收到云端推送的消息。消息有3种类型,分别是:设备状态、云端通知、告警回调。可以通过eventNotify.type进行区分。详见:

[XLinkSDK share].cloudDelegate = self;

-(void)onReceiveEventNotify:(XLinkEventNotify *)eventNotify{
    switch (eventNotify.type) {
        case EventNotifyTypeDataPointChanged:{
        }
            break;

        default:
            break;
    }
}

8  日志功能

SDK运行时会打印日志信息。开发完成后,发布应用时不应显示这些信息。设置setDebug(false)后,SDK不会输出除异常以外的日志信息。

// 配置SDK 
XLinkConfig *config = [[XLinkConfig alloc]init]; 
... .
[config setDebug:NO]; 
... 
[[XLinkSDK share]startWithConfig:config];

进阶使用


1 设备连接状态的刷新

开发app的时候经常需要显示设备的连接状态,很多用例也依赖于设备的连接状态(例如控制设备的时候要求设备在线)。所以如何准确地在app与设备之间同步连接状态是我们首先要解决的问题。设备状态可以通过getConnectionState()XDevice实体中取出,代码如下:


XDevice *device = [[XLinkSDK share].deviceManager getDeviceWithMacAddressString:@"112233445566"];
XDeviceConnectionState connectionState = [device getConnectionState];

对一般开发者来说,设备的连接状态可以用下图表示:sdk_4_3_设备状态图1注:detached状态指设备对象刚生成,尚未进行首次连接状态同步时的状态,一般开发者无需处理。设备可以处于内网连接状态和外网连接状态,可以通过以下代码获取:


XDeviceConnectionState innerConnectionState = [device getLocalConnectionState];
XDeviceConnectionState outterConnectionState = [device getCloudConnectionState];

开发者可以订阅设备的状态变化,如下所示:


 //订阅设备的状态变化
XLinkDeviceStateObserver *observer = [XLinkDeviceStateObserver deviceStateChangedObserverWithDevice:device withDataPointUpdateBlock:^(XDevice *device, XDeviceConnectionState state) {
    switch (state) {
        case XDeviceConnectionStateOnline:
        ...
          break;
        ...
    }
}];
[[XLinkSDK share].deviceManager addDeviceStateObserver:observer];

addDeviceStateObserver会持有XLinkDeviceStateObserver的强引用,所以记得取消订阅以免引起内存泄漏:

//移除订阅设备的状态变化


[[XLinkSDK share].deviceManager removeDeviceStateObserver:observer];

onDeviceStateChanged(XDevice xDevice, XDevice.State status)status的含义如下所示:

含义
XDeviceConnectionStateDetachedXDevice的状态未知
XDeviceConnectionStateOfflineSDK设备与设备失去连接
XDeviceConnectionStateConnectingSDK正在连接设备
XDeviceConnectionStateOnlineSDK设备保持连接

[device getConnectionState]的返回值由[device getLocalConnectionState][device getCloudConnectionState]决定,遵循以下规则:

  1. getConnectionState返回XDeviceConnectionStateOffline时,表示SDK与设备无内外网连接。

  2. getConnectionState返回XDeviceConnectionStateOnline时,表示SDK与设备内外网连接或者内网连接。

  3. getConnectionState返回XDeviceConnectionStateConnecting时,表示SDK与设备无内外网连接,但正在尝试进行内网或者外网连接。

  4. getConnectionState返回XDeviceConnectionStateDetached时,表示SDK尚未尝试过内网或者外网连接。

简单地说,如果开发者不关心设备与SDK的连接方式,只需处理getConnectionState即可。当getConnectionState返回XDeviceConnectionStateOnline时,开发者可向设备发送数据。

2 数据端点的使用

数据端点是对设备运行状态的一种描述,它支持多种数据格式,如布尔、单字节、短整型、长整形以及字符串等。 当设备的数据端点发生变化,若设备已经连接到云端,那数据端点的变化将会通过云智易提供的硬件SDK,同步到云端上,以便厂商在云平台查看与收集设备的运行状态的变化。

端点数据格式

一个设备的数据端点个数最多为200个,每个数据端点由如下格式组成:

数据端点索引数据长度数据
1字节2字节N字节,长度由数据长度决定

注:数据长度的高字节的高4位表示数据类型,数据长度的高字节的低4位和低字节表示数据长度。

端点数据类型

数据类型定义如下:

数据类型(16进制)类型(高字节在前)
1BOOL
2Byte
3Int16
4Int32
5Float
6String
7Binary(二进制数据块)
8Unsigned Int16
9Unsigned Int32
10-F保留

3 服务器推送

前文提到,开发者可以通过XLinkCloudListener接收服务器的推送消息。这里的'推送'不单指通常意义上的文本消息的推送,还包含用户或者设备变化的通知消息。 开发者可以通过EventNotify.type的来判断消息类型,再根据EventNotify.data来处理消息数据。 当消息数据是字符串时,消息数据前两个字节是字符串的长度,其后紧接着数据。消息类型如下表所示:

类型描述
EventNotifyTypeDataPointChanged1设备数据端点变化发送的通知
EventNotifyTypeDataPointAlert2设备数据端点变换引起的报警
EventNotifyTypeDeviceShare3设备管理员推送的分享消息
EventNotifyTypeBoardcast4厂商推送的消息广播
EventNotifyTypeDevicePropChanged5设备属性变化通知
EventNotifyTypeSubscribeChanged6用户和设备订阅关系发生变化通知
EventNotifyTypeDeviceOnlineStateChanged7设备在线状态变化引发的通知
EventNotifyTypeDeviceOnlineStateAlert8设备在线状态变化引发的告警

各类型对应的数据格式如下所示:DATA_POINT_CHANGED


JSON
{
    "index" : 0,
    "value" : 100,
    "msg": 管理台设置的报警内容
}

DATA_POINT_ALERT


JSON
{
    "index" : 0,
    "value" : 100,
    "msg": 管理台设置的报警内容
}

DEVICE_SHARE


JSON
{
    "device_id" : 123457
    "invite_code" : 12345,
    "type":0/1/2/3
}

type: 
0 分享请求
1 接受分享
2 拒绝分享
3 分享被取消
BROADCAST

JSON
{
    "msg_type": "txt",
    "action_type": "url/command",
    "url": "http://xxxx.xxx.xxx",
    "command": "xxxx",
    "title": "xxxx",
    "content": "xxxxx"
}

参数说明
msg_type消息类型,暂时只有txt
action_typeurl/command
url打开链接
command用户自定义动作
url如果action_type是url时的参数
command如果action_type是command时的参数;
title消息标题,UTF-8
content消息内容,UTF-8

DEVICE_PROP_CHANGED

JSON
{
    "device_id" : 123456789
    "type" : "info/prop"
}

type: 
info 设备基本属性变化
prop 设备扩展属性变化
SUBSCRIPTION_CHANGED

JSON
{
    "device_id" : 123456789
    "sub" : 0/1
}

sub:
0 订阅关系取消
1 订阅关系建立
DEVICE_ONLINE_STATE_CHANGED

JSON
{
    "device_id" : 123456789
    "state" : 0 / 1
}

state:
0 离线
1 上线
DEVICE_ONLINE_STATE_ALERT

JSON
{
    "device_id" : 123456789
    "state" : 0 / 1
}

state:
0 离线
1 上线


SDK内置了EventNotifyHelper类方便开发者解析消息推送,使用方法如下:

- (void)onReceiveEventNotify:(XLinkEventNotify *)eventNotify{
    switch (eventNotify.type) {
         case EventNotifyTypeDataPointChanged:
         {
             // 调用对应的解析api来解析data
             SubscriptionChangeNotify *notify = [EventNotifyHelper parseSubscriptionChangeNotifyWithData:eventNotify.data];
             // 处理notify
             ... 
          }
           break;
         ...
 }
注1:开发者在使用sdk时,如果想避免通过轮询的方式来更新状态,应利用上述通知来更新状态。
注2:目前消息通知在服务器端不会缓存,即离线后上线,期间的消息通知不会再次收到。
注3:消息通知功能需用户登录,并使用云平台服务。

4 用户授权管理

调用XLinkUserAuthorizeTask或XLinkThirdPartyAuthorizeTask后,XLinkSDK内部会维护一个XLinkUser对象,里面包含了通讯所需的授权信息:

#pragma mark - 用户基础信息
/**
 用户ID
 */
@property (copy, nonatomic) NSNumber *user_id;

/**
 调用凭证
 */
@property (copy, nonatomic) NSString *access_token;

/**
 刷新凭证
 */
@property (copy, nonatomic) NSString *refresh_token;

/**
 有效期(秒)
 */
@property (copy, nonatomic) NSNumber *expire_in;

/**
 用户认证码
 */
@property (copy, nonatomic) NSString *authorize;


此对象可通过如下方法取出:

XLinkUserModel userModel = [XLinkSDK share].userModel;


请不要修改XLinkUser对象内的授权信息。如果开发者需要取出accesstoken、uid等信息,直接调用XLinkUser对象的get方法即可。值得注意的是,app运行时,XLinkSDK会自动更新XLinkUser内部的授权信息,所以开发者应避免自己缓存XLinkUser里的属性(例如把accessToken存在一个变量里),应在每次需要的时候直接调用XLinkSDK.getUser()取出授权信息

app首次打开时(未有用户信息),应跳转至登录页面让用户登陆。登陆动作应包含运行XLinkUserAuthorizeTask或XLinkThirdPartyAuthorizeTask。如果要实现用户在下次打开app时跳过登陆动作,那么在首次授权时需要保存授权信息,在下次打开app启动SDK前提供授权信息

XLinkUserAuthorizeTask *task = [XLinkUserAuthorizeTask userAuthorizeTaskWithAccount:mAccount withPassword:mPassword withCropId:mCorpId withCompleteBlock:^(id result, NSError *err) {
        if (err) {// 登录失败

        }else {// 登录成功,在result中含有授权信息,SDK内部自动进行云端连接
			// app要保存授权信息,下次打开app跳过登陆的步骤
		    UserModel *user = [[UserModel alloc]init];
    		user.access_token = result[@"access_token"];
    		user.user_id = result[@"user_id"];
    		user.authorize = result[@"authorize"];
    		user.refresh_token = result[@"refresh_token"];
   		    user.expire_in = result[@"expire_in"];
        }
}];
[task start];


再次启动SDK前通过如下方式提供授权信息:
// app要保存授权信息,下次打开app跳过登陆的步骤 
XLinkUserModel *lastUser = [[XLinkUserModel alloc]init]; 
lastUser.access_token = mAccessToken; 
lastUser.user_id = mUserID; 
lastUser.authorize = mAuthorize; 
lastUser.refresh_token = mRefreshToken; 
lastUser.expire_in = mExpireIn;

[XLinkSDK share].xlinkConfig.userModel = lastUser;


设置好以后,在start()的同时,SDK会自动验证授权信息是否合法,合法则进行云端和后续一系列的内部操作。

一般来说,需要重新授权有如下几个原因:

  • 用户被踢出(单点登录)
  • 过期(含缺失,格式错误等原因)
  • 用户主动退出

当出现如上情况时,- (void)onUserLogout:(LogoutReason)reason会回调:

- (void)onUserLogout:(LogoutReason)reason{
	switch (reason) {
        case LogoutReasonSingleSignKickOff://用户被踢出
            break;
            
        case LogoutReasonTokenExpired:// 过期
            break;
            
        case LogoutReasonUserLogout://用户主动退出
            break;
    }
}

注:如果LogoutReason为LogoutReasonSingleSignKickOff或LogoutReasonTokenExpired时,应主动调用[[XLinkSDK share] logoutAndStop]。如果是LogoutReasonUserLogout,则无需主动调用[[XLinkSDK share] logoutAndStop](因为LogoutReasonUserLogout由[[XLinkSDK share] logoutAndStop]触发)。


5 设备订阅关系管理

通过XLinkAddDeviceTask可在云端建立用户和设备之间的订阅关系。订阅关系建立后,可使用XLinkSyncDeviceListTask获取与当前用户有订阅关系的设备列表。通过XLinkRemoveDeviceTask可解除订阅关系。

订阅关系的建立可通过以下途径:

  • 添加设备
  • 设备分享
  • 其他建立云端订阅关系的途径

订阅关系的解除可通过以下途径:

  • 删除设备
  • 设备重新激活(设备重置后再连上云端,设备会重新激活)
  • 其他解除云端订阅关系的途径

在订阅关系建立或解除时,以下两个回调会被触发:

/**
 *  设备属性或者设备状态发生改变时,会回调这个方法。
 *
 *  @param xDevice 发生改变的设备
 */
- (void)onDeviceChanged:(XDevice *)xDevice withEvent:(XDeviceEvent)event{
    switch (event) {
        case XDeviceEventSubscribe://与xDevice的订阅关系建立
            break;
        case XDeviceEventUnSubscribe://与xDevice的订阅关系解除
            break;
        default:
            break;
    }
}
/**
 *  当SDK连接上云端,并接收到云端推送时,会回调这个方法。
 *
 *  @param eventNotify 收到的云端推送信息
 */
- (void)onReceiveEventNotify:(XLinkEventNotify *)eventNotify {
    switch (eventNotify.messageType) {
        case EventNotifyTypeSubscribeChanged:{
            SubscriptionChangeNotify *notify = [EventNotifyHelper parseSubscriptionChangeNotifyWithData:eventNotify.notifyData];
            if (notify.changeType == SubscriptionChangeTypeCancel) {
			// 与xDevice的订阅关系解除
                
            }else if (notify.changeType == SubscriptionChangeTypeEstablish){ 
			// 与xDevice的订阅关系建立
                
            }
        }
            break;
    }
}

开发者选择其中一个进行处理即可。当接收到订阅关系变化的通知时,SDK内部已断开和设备的连接,开发者应主动或提示用户刷新设备列表。

注:以上两个回调依赖云端连接,是云端的推送消息,主要提供给APP开发者处理订阅关系被动建立或被动解除的情况(例如人为重置设备)。如果是用户主动添加或删除设备(XLinkAddDeviceTask或XLinkRemoveDeviceTask),那么在执行成功的时候就要进行后续处理(例如刷新设备列表,更新ui等等),不要等待云端通知再进行处理。


6 设备分享管理

 通过XLinkShareDeviceTask可以将设备权限分享给其他在平台里已经注册的用户。

/**
 创建一个分享设备task
 
 @param device 设备
 @param account 对方账号(邮箱或者手机号)
 @param expired 分享有效期时间(单位秒)
 @param shareDeviceMode 分享的方式
 @param authority 对设备的控制权限,R可读,W可写,RW可读可写;默认为null相当于RW;
 @param timeout task超时时间
 @param shareCompleteBlock 完成后的回调
 @return task
*/
XLinkShareDeviceTask *task = [XLinkShareDeviceTask shareDeviceTaskWithDevice:mDevice withAccount:mAccount withExpired:7200 withShareMode:XLinkShareDeviceModeApp withAuthority:@"RW" withTimeOut:10 withShareDeviceTaskCompleteBlock:^(NSDictionary *result, XLinkErrorCode code) {
        if (!code) {//分享成功

        }else{//分享失败

        }
    }];

[task start];
当接收者在线时候进行分享操作,可以接收到onReceiveEventNotify:的EventNitify,EventNitify的类型是EventNotifyTypeDeviceShare,将EventNitify转换成NSDictionary。如下面代码。
/**
 *  当SDK连接上云端,并接收到云端推送时,会回调这个方法。
 *
 *  @param eventNotify 收到的云端推送信息
 */
- (void)onReceiveEventNotify:(XLinkEventNotify *)eventNotify {
    if (eventNotify.notifyData.length>=2) {
        NSDictionary *recDict = [NSJSONSerialization JSONObjectWithData:[eventNotify.notifyData subdataWithRange:NSMakeRange(2, eventNotify.notifyData.length - 2)] options:NSJSONReadingMutableLeaves error:nil];
       
        if (eventNotify.messageType == EventNotifyTypeDeviceShare) {
            int type = [recDict[@"type"] intValue];
            if (type == 0) {//分享请求
				//可以在这里拿到invite_code,并执行XLinkHandleShareDeviceTask进行处理分享请求的动作
				NSString *inviteCode = recDict[@"invite_code"];
            }else{
                if (type == 1) {//接受分享

                }else if (type == 2){//拒绝分享

                }else if (type == 3){//分享被取消

                }
            }
        }
    }
}
当接收者离线的时候进行分享操作,接收者上线时,应当去获取一次分享列表。具体接口代码如下:
XLinkHttpRequest getShareListWithAccessToken:[XLinkSDK share].userModel.access_token didLoadData:^(id result, NSError *err) {
   	if (!err) {//获取成功
	    //result里面的就是订阅列表数据
        NSArray *dataArray = result;
		[self.dataArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                NSDictionary *dict = obj;
                //还在有限期内没有处理的分享请求,可以去进行处理
                if ([dict[@"state"] isEqualToString:@"pending"]) {
					//拿到invite_code,并执行XLinkHandleShareDeviceTask进行处理分享请求的动作
                    NSString *inviteCode = dict[@"invite_code"];
                }
            }];
   	}
}];
通过前面的两个方法,可以拿到invite_code,然后执行XLinkHandleShareDeviceTask进行处理分享请求的动作。


XLinkHandleShareDeviceTask *handleTask = [XLinkHandleShareDeviceTask handleShareDeviceTaskWithInvitedCode:invite_code withHandleShareAction:XLinkHandleShareDeviceActionAccept withTimeOut:20 withTaskCompleteBlock:^(XLinkErrorCode code) {
     if(!code){//处理成功

	 }else{//处理失败

	 }
}];
[handleTask start];

7 Restful API


SDK包装了部分常用的Restful API,例如用户注册、登陆、找回密码等等。完整的Restful API文档在:Restful API文档
用户通过如下方式可调用Restful API:
//获取用户详细信息
[XLinkHttpRequest getUserInfoWithUserID:mUserId withAccessToken:mToken didLoadData:^(id result, NSError *err) {
    if(err){//获取失败

	}else{//获取成功

	}
}];

若SDK自带Restful API接口不能满足需求,开发者需自己实现,可通过如下方式:

1、添加XLinkHttpRequest的扩展(Category),并添加相关的方法,网络请求可以调用XLinkHttpRequest中的

(+requestWithRequestType:WithUrl:withHeader:withContent:withDidLoadData:)
例如实现home相关的方法时,可以创建XLinkHttpRequest+home,并根据功能添加相关代码,下面例子是一个创建home的方法。
/**
 *  1.1 创建Home
 *
 *  @param name        home 名字
 *  @param accessToken 调用凭证
 *  @param block       完成后回调
 */
+ (void)createHomeWithName:(NSString *)name withAccessToken:(NSString *)accessToken didLoadData:(RequestCompleteBlock)block{
    if (!accessToken) {
        if (block) block(nil, [NSError errorWithDomain:CustomErrorDomain code:4031003 userInfo:ErrorParam(@"access token")]);
        return;
    }
    [self requestWithRequestType:RequestTypePOST withUrl:@"/v2/home" withHeader:@{@"Access-Token":accessToken}  withContent:@{@"name":name} withDidLoadData:block];
}
2、按照文档Restful API文档,自己选择适合的库(如AFNetworking)去实现相关的需求。

注意:

若开发者使用其他方式,要注意AccessToken必须从SDK中的UserModel取出,即当开发者调用需要accesstoken的接口时,必须使用[XLinkSDK share].userModel的属性中的access_token,并且不要缓存起来使用(例如保存在一个变量中)。因为SDK会管理access_token,防止其过期,所以在SDK运行过程中,有可能access_token已经刷新过。

8 Demo

开发者在使用SDK的过程中可参考iOS SDK (V5) Demo,DEMO实现了上述各个API的调用.



编写评论...