DCA SDK集成(iOS)

1.前言

DCA SDK是运行在手机端的配套app的sdk。

DCA 相关功能全都依赖于设备端(比如音箱等)的DDS SDK配置oauth信息(userid,authcode等),才能使得DCA的功能生效。

DCA SDK需先进行登录才能正常使用。

若需要接入内容资源,请联系思必驰项目经理或在“APP开发->客户咨询”联系我们。

2.集成准备

先在DUI开放平台注册一个账号成为开发者,并登录APP管理后台申请apiKey、apiSecret、manufacture、clientid等一些集成SDK需要的参数;具体流程参考DCA SDK创建引导

apiKey:集成SDK时需用到的鉴权参数

apiSecret:集成SDK时需用到的鉴权参数

manufacture:厂商标识的明文,由开发者自己取名(英文名,不超过20位);当开发者使用自有账号时,贵司账号与思必驰账号互通时用到

manufacture_secret:厂商标识对应的密文,当开发者使用自有账号时,贵司账号与思必驰账号互通时用到

设备oauth授权的clientId:用于DDS SDK的账号授权

3.集成 DCA SDK

3.1 导入SDK

将iOS_DCA_SDK.framework,DCAToolsSDK.framework导入工程

3.2 添加依赖库

使用cocoapod 导入使用到的第三方库(或直接下载导入源码到工程中):

platform :ios, ‘9.0’

target '项目名' do
use_frameworks!

pod 'CocoaMQTT', '~> 1.2.5'
pod 'CocoaAsyncSocket', '~> 7.6.3'
pod 'Alamofire', '~> 4.8'
pod 'YYKit', '~> 1.0.9'

end

关于iOS16使用MQTT库时,MQTT库会调用CocoaAsyncSocket,CocoaAsyncSocket内部使用了废弃的方法导致崩溃,需要对CocoaAsyncSocket进行如下图修改:

现在参考的链接:https://github.com/robbiehanson/CocoaAsyncSocket/pull/804

 

3.3 添加权限

最简单的方法在Info.plist中添加以下字段:

//网络
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
 
 
//蓝牙(iOS13以上必须,用于蓝牙和声波配网功能)
<key>NSBluetoothAlwaysUsageDescription</key>
<string>您的蓝牙将用于连接智能设备</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>您的蓝牙将用于连接智能设备</string>

3.4 注意事项

1.工程 Enable Bitcode 设置为 NO;

2.导入OC项目中先随意创建一个Swift文件生成桥文件XXXX-Bridging-Header,然后引入头文件 #import <iOS_DCA_SDK/iOS_DCA_SDK.h>;

3.导入Swift项目,直接引入头文件 import iOS_DCA_SDK;

4.SDK使用之前需进行登录操作;

5.绑定设备成功或者在绑定了多设备情况下切换至当前选择的设备时都需将deviceId进行赋值([DCAManager.shared setDeviceId:@""]);

6.如果使用Xcode10.1打开项目集成SDK的话,需要使用提供的低版本SDK,并且修改Swift Language Version为4.2


3.5 初始化参数以及代理实现

@interface AppDelegate ()<DCAManagerDelegate>

@end


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Override point for customization after application launch.

    //初始化dca sdk,需要申请apiKey,apiSecret
    [[DCAManager shared] initializeWithApiKey:@"" apiSecret:@""];

    //设置代理
    [[DCAManager shared] setDelegate:self];

    //查看SDK版本号(需要查看的时候调用即可)
    NSLog(@"%@",[[DCAManager shared] getSDKVersion]);

    return YES;

}


#pragma mark - DCAManagerDelegate
//SDK没有登录或SDK内部刷新token失败情况下会走此回调
-(void)onNeedLogin {

    NSLog(@"请登录");
}

4.账号相关

开发者在集成账号登录有如下两种方式可选:

1.使用思必驰账号系统

2.客户使用自有账号系统

4.1 使用思必驰账号系统

4.1.1 获取验证码

//获取相应验证码
@objc public enum SMSCODETYPE:Int {

    /// 登录
    case LOGIN       = 1

    /// 忘记密码
    case FORGETPW    = 2

    /// 手机号绑定(仅支持手机验证码)
    case BINDINGPHONE = 4
}
requestModel

requestModel

callBack

回调 (状态码+msg)

GetCodeRequestModel *model = [[GetCodeRequestModel alloc] init];
model.userName = @"";
model.type = SMSCODETYPELOGIN;
//非必传
//model.signName = @"";
//model.templateCode = @"";

[[[DCAManager shared] accountManager] getVerifyCodeWithRequestModel:model type:SMSCODETYPELOGIN callBack:^(NSString * errCode, NSString * msg) {

}];

4.1.2 登录

request

登录请求request

callBack

回调 (状态码+msg+数据)

LoginRequest *request = [[LoginRequest alloc] init];
request.userName = @"";
request.password = @"";
request.smsCode = @"";
[[[DCAManager shared ] accountManager] loginWithRequest:request callBack:^(NSString * errCode, NSString * msg, AccountModel * data) {

}];

4.1.3 手机号或邮箱验证(忘记密码时先获取验证码,通过此接口验证通过后才能重新设置密码)

request

手机号或邮箱验证参数request

callBack

回调 (状态码+msg+数据)

VerifyRequest *request = [[VerifyRequest alloc] init];
request.userName = @"";
request.smsCode = @"";
[[[DCAManager shared ] accountManager] verifyUserNameBySmsCodeWithRequest:request callBack:^(NSString * errCode, NSString * msg, AccountModel * data) {

}];

4.1.4 初始化密码

request

初始化密码参数request

callBack

回调 (状态码+msg+数据)

InitPasswordRequest *request = [[InitPasswordRequest alloc] init];
request.userName = @"";
request.password = @"";
request.pwCredential = @"";
[[[DCAManager shared ] accountManager] initPasswordWithRequest:request callBack:^(NSString * errCode, NSString * msg, NSDictionary * dic) {

}];

4.1.5 设置密码

request

设置密码参数request

callBack

回调 (状态码+msg+数据)

SetPasswordRequest *request = [[SetPasswordRequest alloc] init];
request.userId = @"";
request.token = @"";
request.password = @"";
[[[DCAManager shared ] accountManager] setPasswordWithRequest:request callBack:^(NSString * errCode, NSString * msg, NSDictionary * dic) {

}];

4.1.6 微信登录

request

微信登录请求request

callBack

回调 (状态码+msg+数据)

WeChatLoginRequest *request = [[WeChatLoginRequest alloc] init];
request.unionId = @"";
request.openId = @"";
request.nickName = @"";
request.headImgUrl = @"";
request.allowCreate = NO;
[[[DCAManager shared] accountManager] loginByWeChatWithRequest:request callBack:^(NSString * errCode, NSString * msg, AccountModel * data) {

}];

4.1.7 关联手机号

request

关联手机号请求request

callBack

回调 (状态码+msg+数据)

//注意:此处的验证码smsCode,调用发送验证码接口时需要传的类型为BINDINGPHONE
LinkPhoneRequest *request = [[LinkPhoneRequest alloc] init];
request.unionId = @"";
request.openId = @"";
request.nickName = @"";
request.headImgUrl = @"";
request.mobile = @"";
request.smsCode = @"";
[[[DCAManager shared] accountManager] linkPhoneNumWithRequest:request callBack:^(NSString * errCode, NSString * msg, AccountModel * data) {

}];

4.2 使用贵司自有账号系统

在实际项目中,贵司有自己的账号系统或指定其他的账号系统,需要和思必驰账号打通,打通后即可使用自有账号系统,具体流程如下:
1)c端用户在贵司的配套APP注册登录,登录成功后贵司从自身云端获取该c端用户的UID和AccessToken;
2)贵司调用SDK的账号接口,传入上述的UID和AccessToken;
3)思必驰云端接收到贵司的UID和AccessToken,并与贵司云端互通校验UID和AccessToken(贵司需要提供一个校验接口,方便思必驰云端和贵司服务端互通);
4)贵司返回给思必驰校验结果后,思必驰基于合法的贵司的UID生成思必驰账号;
5)思必驰云端将思必驰账号的userID传给DCA SDK,实现SDK登录授权

6)accesstoken的有效期是2小时,refresh token的有效期为2年,生成有效参数后,配套app会将参数传输给dds sdk(具体可查看dds sdk文档),后续维护均在dds sdk(设备侧)中,需要保持设备在2年内通电通网,不然可能会造成授权失效,需重新绑定设备,才可再次进行授权。

4.2.1 贵司账号和思必驰账号对接接口

该接口只需要在登录或者切换账号后调用

thirdPlatformUid

填写贵司系统用户ID

thirdPlatformToken

填写用来访问贵司uid校验服务的token

manufactureSecret

填写用来访问贵司uid校验服务的secret

callBack

回调 (状态码+msg+数据)

[[[DCAManager shared] accountManager] linkAcountWithThirdPlatformUid:@"" thirdPlatformToken:@"" manufactureSecret:@"" callBack:^(NSString * errCode, NSString * msg, AccountModel * data) {

}];


同时,这里需要贵司服务端实现如下接口:

(贵司需要实现的接口)
本接口内部需要访问贵司提供的UID校验的接口,需要提供的接口格式如下:
POST /%external-platform-path%
 
{"uid":"xxx","token":"xxx"}
 
成功: 200  {"code":"SUCCESS","message":"success!"}
失败: 200  {"code":"ACCOUNT_NOT_EXIST","message":"account is not exist!"}
 
参数说明:
uid:    贵司帐号系统用户ID
token:  用来访问贵司uid校验服务的token
 
code 说明
SUCCESS:                 uid校验通过
ACCOUNT_NOT_EXIST:       账号不存在
INVALIDATE_PARAMS:       参数错误
TOKEN_INVALIDATE:        token无效(包括失效)

4.3 获取userId和accessToken

//获取userId
[[[DCAManager shared] accountManager] getUserId];


//获取accessToken
[[[DCAManager shared] accountManager] getAccessToken];

5.用户相关

如果查找用户信息接口data返回null则需要先调用首次上传用户信息接口

5.1 获取用户信息

userId

用户id

callBack

回调(状态码+msg+数据)

[[DCAManager shared] userManager] getUserInfoWithUserId:@"" callBack:^(NSString * errCode, NSString * msg, UserInfoModel * data) {

}];

5.2 首次上传用户信息

nickname

昵称

phone

手机号

gender

性别 MALE-男,FAMALE-女,UNKNOWN-未知

headUrl

头像链接地址

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] userManager] registerFirstWithNickname:@"" phone:@"" gender:GENDERMALE headUrl:@"" callBack:^(NSString * errCode, NSString * msg, UserInfoModel * data) {

}];

5.3 更换头像

data

头像数据

callBack

回调(状态码+msg+数据)

//示例
UIImage *img = [UIImage imageNamed:@""];
NSData *data = UIImageJPEGRepresentation(img, 0.5);

[[[DCAManager shared] userManager] setHeadImgWithData:data callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

5.4 修改昵称

nickname

昵称

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] userManager] setNicknameWithNickname:@"" callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

5.5 修改性别

gender

性别 MALE-男,FAMALE-女

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] userManager] setGenderWithGender:GENDERMALE callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

5.6 获取宝宝资料

[[[DCAManager shared] userManager] getBabyDataWithCallBack:^(NSString * errCode, NSString * msg, BabyDataModel * data) {

}];

5.7 保存宝宝资料

born

出生日期 毫秒级时间戳

relation

关系 (传爸爸、妈妈、爷爷、奶奶、外公、外婆其中一种)

gender

性别 MALE-男,FAMALE-女

babyInfoId

宝宝信息id(getBabyData接口获取,首次保存传空)

callBack

回调(状态码+msg)

[[[DCAManager shared] userManager] saveBabyDataWithBorn:@"" relation:@"" gender:GENDERMALE babyInfoId:@"" callBack:^(NSString * errCode, NSString * msg) {

}];

5.8 收藏

5.8.1 获取收藏列表

page

页数

count

每页数量

callBack

回调(状态码+msg+总页数+数据)

[[[DCAManager shared] userManager] getCollectionListWithPage:1 count:20 callBack:^(NSString * errCode, NSString * msg, NSInteger totalPage, NSArray<ChildAlbumBrowseModel *> * data) {

}];

5.8.2 添加收藏

model

歌曲model,ChildAlbumBrowseModel

callBack

回调(状态码+msg+数据)

ChildAlbumBrowseModel *model = [[ChildAlbumBrowseModel alloc] init];//需要添加收藏的歌曲model
[[[DCAManager shared] userManager] addModelInCollectionWithModel:model callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

5.8.3 删除收藏

model

歌曲model,ChildAlbumBrowseModel

callBack

回调(状态码+msg+数据)

ChildAlbumBrowseModel *model = [[ChildAlbumBrowseModel alloc] init];//需要移除收藏的歌曲model
[[[DCAManager shared] userManager] deleteModelInCollectionWithModel:model callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

5.9 通讯录

5.9.1 获取通讯录

[[[DCAManager shared] userManager] getContactsWithCallBack:^(NSString * errCode, NSString * msg, NSInteger validate, NSArray<FamilyAddressBookListModel *> * data) {

}];

5.9.2 添加通讯录

nickname

昵称

relation

关系

phone

电话号码

callBack

回调(状态码+msg)

[[[DCAManager shared] userManager] addContactWithNickname:@"" relation:@"" phone:@"" callBack:^(NSString * errCode, NSString * msg) {

}];

5.9.3 获取用户个人二维码

[[[DCAManager shared] userManager] getUserQRCodeWithCallBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

5.9.4 扫码添加到通讯录,无需同意

nickname

用户昵称

relation

关系

userId

对方用户id

callBack

回调(状态码+msg)

[[[DCAManager shared] userManager] addQRContactWithNickname:@"" relation:@"" userId:@"" callBack:^(NSString * errCode, NSString * msg) {

}];

5.9.5 获取好友申请列表

[[[DCAManager shared] userManager] getNewFriendsWithCallBack:^(NSString * errCode, NSString * msg, NSArray<FamilyAddressBookListModel *> * data) {

}];

5.9.6 同意好友申请

model

好友申请列表model

callBack

回调(状态码+msg)

[[[DCAManager shared] userManager] agreeContactRequestWithModel:model callBack:^(NSString * errCode, NSString * msg) {

}];

5.9.7 编辑通讯录好友信息

nickname

昵称

relation

关系

editId

被编辑者userId,对应FamilyAddressBookListModel中的userId

fbId

FamilyAddressBookListModel中的fbId

callBack

回调(状态码+msg)

[[[DCAManager shared] userManager] editContactWithNickname:@"" relation:@"" editId:@"" fbId:@"" callBack:^(NSString * errCode, NSString * msg) {

}];

5.9.8 删除通讯录好友

fbId

通讯录id

callBack

回调(状态码+msg)

[[[DCAManager shared] userManager] deleteContactWithFbId:@"" callBack:^(NSString * errCode, NSString * msg) {

}];

5.10 自定义问答

5.10.1 初始化qa信息,获取QaInitResult,其中的值需要在后续操作中使用

[[[DCAManager shared] userManager] initQaWithCallBack:^(NSString * errCode, NSString * msg, QaInitModel * data) {

}];

5.10.2 获取知识点问答信息

qaInitModel

qaInitModel(initQa接口返回)

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] userManager] queryQaInfoWithQaInitModel:qaInitModel callBack:^(NSString * errCode, NSString * msg, NSArray<QaInfoModel *> * data) {

}];

5.10.3 根据kid获取知识点问答详情

kid

获取知识点问答信息接口中获取

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] userManager] queryQaInfoDetailWithKid:@"" callBack:^(NSString * errCode, NSString * msg, QaInfoModel * data) {

}];

5.10.4 新增知识点问答对

qaInitModel

初始化获取的model(initQa获取)

questionNameArr

自定义问题

answerNameArr

自定义答复

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] userManager] addQaInfoWithQaInitModel:qaInitModel questionNameArr:@[@""] answerNameArr:@[@""] callBack:^(NSString * errCode, NSString * msg, QaInfoModel * data) {

}];

5.10.5 根据kid,删除知识点

kid

知识点id,由QaInfo的QaTopicKnowledgeModel的kid获取到

callBack

回调(状态码+msg)

[[[DCAManager shared] userManager] deleteQaInfoWithKid:@"" callBack:^(NSString * errCode, NSString * msg) {

}];

5.10.6 更新知识点问答对

注意:需要在调用根据kid获取知识点问答详情接口成功后再进行更新

qaInfoModel

QaInfoModel

callBack

回调(状态码+msg+数据)

QaInfoModel *infoModel = [[QaInfoModel alloc] init];
infoModel = self.qaInfoModel;//需要更新的那个qaInfoModel
NSMutableArray *qMutArr = [[NSMutableArray alloc] initWithArray:infoModel.question];
QaQuestionModel *questionModel1 = [QaQuestionModel new];
questionModel1.questionName = @"我是谁";
[qMutArr addObject:questionModel1];
infoModel.question = qMutArr;
NSMutableArray *aMutArr = [[NSMutableArray alloc] initWithArray:infoModel.answer];
QaAnswerModel *answerModel1 = [QaAnswerModel new];
answerModel1.answerName = @"你是我的主人啊";
[aMutArr addObject:answerModel1];
infoModel.answer = aMutArr;

[[[DCAManager shared] userManager] updateQaInfoWithQaInfoModel:infoModel callBack:^(NSString * errCode, NSString * msg, QaInfoModel * data) {

}];

5.10.7 使得修改的数据在语音对话中生效, 每次调用其他接口修改数据后,都要调用这个接口

qaInitModel

初始化获取的model(initQa获取)

callBack

回调(状态码+msg)

[[[DCAManager shared] userManager] effectiveQaOperationWithQaInitModel:qaInitModel callBack:^(NSString * errCode, NSString * msg) {

}];

6.APP信息相关

6.1 广告

[[[DCAManager shared] appManager] getAdvertisementListDataWithCallBack:^(NSString * errCode, NSString * msg, AdvertisementModel * data) {

}];

6.2 轮播图

[[[DCAManager shared] appManager] getCarouselDataWithCallBack:^(NSString * errCode, NSString * msg, NSArray<ChildCarouselModel *> * data) {

}];

6.3 用户反馈

type

问题类型:"设备配网","设备使用","APP使用","功能和设计建议","音乐有声等内容","技能问题","其他"

userPhone

用户手机号

content

反馈内容

imageUrl

图片(图片链接数组字符串)

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] appManager] feedBackWithType:@"" userPhone:@"" content:@"" imageUrl:@"" callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

6.4 加载协议等相关信息

[[[DCAManager shared] appManager] loadAboutUsMsgDataWithCallBack:^(NSString * errCode, NSString * msg, AboutUsH5UrlModel * data) {

}];

6.5 app是否需要更新

version

版本号 V1.0.0

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] appManager] checkAppVersionWithVersion:@"V1.0.0" callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

7.设备配网

7.1 蓝牙配网

7.1.1 初始化蓝牙配网

BluetoothState状态说明

/// 蓝牙开关状态
typedef SWIFT_ENUM(NSInteger, BluetoothState, closed) {
/// 蓝牙打开
  BluetoothStateBluetoothOpen = 0,
/// 蓝牙关闭
  BluetoothStateBluetoothClose = 1,
};
[[[DCAManager shared] bleNetManager] initBleNetworkWithBleState:^(BluetoothState state) {

}];

7.1.2 开始搜索蓝牙设备

[[[DCAManager shared] bleNetManager] startDiscoverBleWithBleData:^(NSDictionary * dic) {

}];

7.1.3 配网

BleNetworkState状态说明

/// 设备配网状态
typedef SWIFT_ENUM(NSInteger, BleNetworkState, closed) {
/// 配网成功
  BleNetworkStateBleNetworkSuccess = 0,
/// 配网失败
  BleNetworkStateBleNetworkFailure = 1,
/// 配网中
  BleNetworkStateBleNetworkConnecting = 2,
};
peripheral

蓝牙信息

ssid

wifi名称

pwd

wifi密码

vc

当前控制器

bleNetResult

配网状态+msg+结果数据(配网成功会返回deviceId+productId+clientId三个参数)

[[[DCAManager shared] bleNetManager] sendDataToDeviceWithPeripheral:peripheral ssid:@"" pwd:@"" vc:self bleNetResult:^(BleNetworkState state,NSString * msg, NSDictionary * dic) {

}];

7.1.4 关闭蓝牙搜索

[[[DCAManager shared] bleNetManager] stopDiscoverBle];

7.1.5 dealloc

[[[DCAManager shared] bleNetManager] deallocBleNetwork];

7.2 声波配网

7.2.1 初始化声波配网

[[[DCAManager shared] sonicNetManager] initSonicNetwork];

7.2.2 开启声波播放并进行配网

SonicNetworkState状态说明

/// 设备配网状态
typedef SWIFT_ENUM(NSInteger, SonicNetworkState, closed) {
/// 配网成功
  SonicNetworkStateSonicNetworkSuccess = 0,
/// 配网失败
  SonicNetworkStateSonicNetworkFailure = 1,
/// 配网中
  SonicNetworkStateSonicNetworkConnecting = 2,
};
wifiStr

wifi名称

pwd

wifi密码

sonicNetResult

配网状态+msg+结果数据(配网成功会返回deviceId+productId+clientId三个参数)

[[[DCAManager shared] sonicNetManager] startSonicNetworkWithWifiStr:@"" pwd:@"" sonicNetResult:^(SonicNetworkState state,NSString *msg, NSDictionary * dic) {

}];

7.2.3 关闭声波

[[[DCAManager shared] sonicNetManager] stopSonicNetwork];

7.2.4 dealloc

[[[DCAManager shared] sonicNetManager] deallocSonicNetwork];

7.3 扫码配网

说明:扫码配网之前需先上传用户信息数据(接口5.1如果获取数据为null,则调用接口5.2进行首次上传)

7.3.1 扫码获取链接

//扫码成功后可获得一个如以下格式的用以配网+授权相关的链接
https://pdca.duiopen.com/mobile-app/api/app/account/scan?deviceId=XXX&productId=XXX&clientId=XXX

7.3.2 获取authCode

redirectUrl

redirectUrl(暂时默认"http://dui.callback")

clientId

clientId

isScan

是否为扫码进行配网

callBack

回调(errCode+authCode)

 

[[[DCAManager shared] deviceManager] requestAuthCodeWithRedirectUrl:@"http://dui.callback" clientId:@"" isScan:true callBack:^(NSString * errCode, NSString * authCode) {

}];

7.3.3 发送authCode等相关信息

deviceId

设备id

authCode

authCode

isScan

是否为扫描二维码配网

callBack

回调(状态码+msg+数据)

 

//注意:此接口调用成功后再去走绑定设备流程
[[[DCAManager shared] deviceManager] sendAuthCodeWithDeviceId:@"" authCode:@"" isScan:true callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

7.3.4 带屏设备同步解绑

注意:如果贵公司对接的设备为带屏设备,那么客户端在调用http解绑接口成功后,需要使用MQTT发送一个解绑消息给到设备端使设备同步解绑(先连接MQTT调用接口12.1.1,连接成功后向指定的topic发送解绑消息即可)。

 

//发送解绑信息
NSMutableDictionary *mutDic = [[NSMutableDictionary alloc] init];
[mutDic setValue:@"" forKey:@"name"];//设备名
[mutDic setValue:@"" forKey:@"userid"];//思必驰userId
[mutDic setValue:@"" forKey:@"deviceid"];//设备id
[mutDic setValue:@"unbind" forKey:@"do"];
[mutDic setValue:@"" forKey:@"data"];//自定义内容,默认传空字符串

NSString *jsonStr = [self getJSONStringWithDictionary: mutDic];//将字典转成json字符串

//MQTT发送解绑消息
[[[DCAManager shared] deviceControlManager] sendDataWithTopic:@"设备id" jsonStr:jsonStr];

7.4 AP配网

/// 设备配网状态
typedef SWIFT_ENUM(NSInteger, APNetworkState, closed) {
  /// 配网成功
  APNetworkStateAPNetworkSuccess = 0,
  /// 配网失败
  APNetworkStateAPNetworkFailure = 1,
  /// 配网中
  APNetworkStateAPNetworkConnecting = 2,
};
wifiStr

正常可用的WiFi账号

pwd

正常可用的WiFi密码

apNetResult

ap配网状态+结果数据

 

/*
1.搜索周边设备(音箱)发出的wifi热点;
2.选择对应的wifi热点(设备)进行连接;
3.输入一个已知的正确可用的wifi账号+密码调用下面接口,监听配网结果即可
*/
[[[DCAManager shared] apNetManager] startAPNetworkWithWifiStr:@"" pwd:@"" apNetResult:^(APNetworkState state,NSString * msg, NSDictionary * dic) {
        
}];

8.设备相关接口

8.1 绑定设备

当您成功为设备配网后,需要调用本接口来为用户绑定设备。

注:

1. 一台设备只能被一个用户绑定;一个用户可以绑定多台设备。

2. 若已绑定设备的信息需要更新,如deviceAlias、deviceInfo,也可以调用本接口

deviceData

需要绑定的设备的设备信息

callBack

回调(数据)

/*

绑定成功后记得调用[[DCAManager shared] setDeviceId:@""]进行赋值

*/

NSMutableDictionary * dic1 = [NSMutableDictionary new];
//设备类型(必填)
[dic1 setValue:@"音箱" forKey:@"deviceType"];
//设备ID(必填)
[dic1 setValue:@"" forKey:@"deviceName"];
//设备名称(必填)
[dic1 setValue:@"思必驰音箱" forKey:@"deviceAlias"];
NSMutableDictionary * dic2 = [NSMutableDictionary new];
//产品ID(必填)
[dic2 setValue:@"" forKey:@"productId"];
//deviceInfo中可自行补充其他所需参数
[dic1 setValue:dic2 forKey:@"deviceInfo"];

[[[DCAManager shared] deviceManager] bindDeviceWithDeviceData:dic1 callBack:^(NSDictionary * data) {

}];

8.2 解除绑定

[[[DCAManager shared] deviceManager] unbindDeviceWithCallBack:^(NSDictionary * data) {

}];

8.3 获取绑定设备列表

[[[DCAManager shared] deviceManager] getBindDeviceListWithCallBack:^(NSDictionary * data) {

}];

8.4 查询设备实时状态和信息

[[[DCAManager shared] deviceManager] getDeviceCurrentStateWithCallBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

8.5 获取设备概览

[[[DCAManager shared] deviceManager] getDeviceBasicInfoWithCallBack:^(NSString * errCode, NSString * msg, EquipDeviceInfoModel * data) {

}];

8.6 闹钟

8.6.1 获取闹钟列表

[[[DCAManager shared] deviceManager] getAlarmListWithCallBack:^(NSString * errCode, NSString * msg, NSArray<EquipAlarmModel *> * data) {

}];

8.6.2 新增闹钟

alarmDate

响铃日期,格式如20190314

alarmTime

响铃时间,格式如08:00:00

repeatStr

重复规则,单次为"“,如果重复,则为([W1][W2][W3][W4][W5][W6][W7]),举例如W1W2W3

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] deviceManager] addAlarmWithAlarmDate:@"" alarmTime:@"" repeatStr:@"" callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

8.6.3 删除闹钟

[[[DCAManager shared] deviceManager] deleteAlarmWithAlarmIds:@[] callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

8.7 日程提醒

8.7.1 获取日程提醒列表

[[[DCAManager shared] deviceManager] getRemindListWithCallBack:^(NSString * errCode, NSString * msg, NSArray<EquipRemindModel *> * data) {

}];

8.7.2 新增日程提醒

remindDate

日程日期,格式如20190314

remindTime

日程时间,格式如08:00:00

event

日程提醒内容

repeatStr

重复规则,单次为"“,如果重复,则为([W1][W2][W3][W4][W5][W6][W7]),举例如W1W2W3

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] deviceManager] addRemindWithRemindDate:@"" remindTime:@"" event:@"" repeatStr:@"" callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

8.7.3 删除日程提醒

remindIds

需要删除的日程提醒id数组

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] deviceManager] deleteRemindWithRemindIds:@[] callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

8.8 打开或关闭蓝牙

model

状态 YES打开 NO关闭

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] deviceManager] setBleActivatedWithModel:NO callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

8.9 打开或关闭就近唤醒

state

状态 0打开 1关闭

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] deviceManager] setWakeUpFunctionWithState:0 callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

8.10 语音留言

8.10.1 获取语音留言

page

页数

count

每页数量

callBack

回调(状态码+msg+总页数+数据)

[[[DCAManager shared] deviceManager] getMessagesWithPage:1 count:20 callBack:^(NSString * errCode, NSString * msg, NSInteger totalPage, NSArray<EquipVoiceMessageModel *> * data) {

}];

8.10.2 上传语音留言

data

录音文件(amr格式文件)

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] deviceManager] sendVoiceMessageWithData:amrData callBack:^(NSString * errCode, NSString * msg) {

}];

8.10.3 获取语音留言未读数

[[[DCAManager shared] deviceManager] getUnReadMessageCountWithCallBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

8.10.4 将留言未读转换成已读

chatId

留言id

callBack

回调(状态码+msg)

[[[DCAManager shared] deviceManager] readVoiceMessageWithChatId:@"" callBack:^(NSString * errCode, NSString * msg) {

}];

8.11 群聊

8.11.1 获取群聊列表

[[[DCAManager shared] deviceManager] getGroupChatsWithCallBack:^(NSString * errCode, NSString * msg, NSArray<FamilyGroupChatListModel *> * data) {

}];

8.11.2 创建群聊

groupName

群聊名称

userIds

群聊成员id

callBack

回调(状态码+msg)

[[[DCAManager shared] deviceManager] createGroupChatWithGroupName:@"" userIds:@[@""] callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

8.11.3 获取某个群的聊天记录

chatId

群聊id

page

页数

count

每页数量

callBack

回调(状态码+msg+未读消息id数组+数据)

[[[DCAManager shared] deviceManager] getGroupChatMessageWithChatId:@"" page:1 count:20 callBack:^(NSString * errCode, NSString * msg, NSArray * unReadArr, NSArray<FGCDetailListModel *> * data) {

}];

8.11.4 发送聊天信息

chatId

群聊id

data

语音数据,amr格式文件

callBack

回调(状态码+msg)

[[[DCAManager shared] deviceManager] sendGroupMessageWithChatId:@"" data:amrData callBack:^(NSString * errCode, NSString * msg) {

}];

8.11.5 将群聊消息置为已读

chatId

群聊id

recordId

消息id

callBack

回调(状态码+msg)

[[[DCAManager shared] deviceManager] readGroupChatMessageWithChatId:@"" recordId:@"" callBack:^(NSString * errCode, NSString * msg) {

}];

8.12 对话记录

productId

绑定设备时获取的值

seqId 消息拉取的起始seqId,选填,填nil或者空字符串则默认返回最新的消息
count

拉取消息个数

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] deviceManager] getDialogRecordWithProductId:@"" seqId:nil count:20 callBack:^(NSDictionary * data) {

}];

返回格式如下:

inputText为语音输入,dmOutput为对话输出,其中的nlg为tts播报内容

返回的对话消息为逆序, 最下面的是最新消息

{
    "errorId":0,
    "result":[
        {
            "seqId":1541573331577000,
            "dmOutput":{
                "dm":{
                    "widget":{
                        "type":"text",
                        "text":"保持微笑吧!老天爷眷顾爱笑的人"
                    },
                    "shouldEndSession":false,
                    "skillId":"2018042100000005",
                    "speak":{
                        "type":"text",
                        "text":"保持微笑吧!老天爷眷顾爱笑的人"
                    },
                    "status":0,
                    "nlg":"保持微笑吧!老天爷眷顾爱笑的人"
                },
                "skillId":"2018042100000005",
                "recordId":"2a34431dbb60ec525122616a2a5b4ece",
                "contextId":"5b1af9cc2df9f5cfccf80455b3c8faf1",
                "sessionId":"5b1af9cc2df9f5cfccf80455b3c8faf1",
                "error":{
                    "errMsg":"ba skill respond ok.",
                    "errId":"010507"
                },
                "nlu":{
                    "timestamp":1541573330,
                    "skillId":"2018042100000005",
                    "skill":"新百科",
                    "input":"今天天气怎么样",
                    "skillVersion":"2"
                }
            },
            "inputText":"今天天气怎么样"
        },
        {
            "seqId":1541573756014000,
            "dmOutput":{
                "dm":{
                    "widget":{
                        "type":"text",
                        "text":"我猜你是我的主人呀,嘿嘿,猜对了吧"
                    },
                    "shouldEndSession":false,
                    "skillId":"2018042100000005",
                    "speak":{
                        "type":"text",
                        "text":"我猜你是我的主人呀,嘿嘿,猜对了吧"
                    },
                    "status":0,
                    "nlg":"我猜你是我的主人呀,嘿嘿,猜对了吧"
                },
                "skillId":"2018042100000005",
                "recordId":"c8a3e2653c034f5472b072d55d7da607",
                "contextId":"22d091033fab7de156b9f69479a54af9",
                "sessionId":"22d091033fab7de156b9f69479a54af9",
                "error":{
                    "errMsg":"ba skill respond ok.",
                    "errId":"010507"
                },
                "nlu":{
                    "timestamp":1541573755,
                    "skillId":"2018042100000005",
                    "skill":"新百科",
                    "input":"猜猜我是谁",
                    "skillVersion":"2"
                }
            },
            "inputText":"猜猜我是谁"
        }
    ]
}

8.13 场景模式

8.13.1 创建场景模式

quickCreateRequest说明:

sentences:快捷指令(场景)的trigger条件,比如“我回家了”“我下班了”
commands:触发快捷场景后设备执行的多个操作指令,比如“打开开关”,“播放周杰伦的歌”

productId

产品Id

quickCreateRequest

quickCreateRequest

callBack

回调(状态码+msg+数据)

QuickCreateRequest *quickCreateRequest = [[QuickCreateRequest alloc] init];
quickCreateRequest.sentences = @[@"我去上班了"];
CommandRequest *request1 = [[CommandRequest alloc] init];
request1.text = @"开空调";
request1.type = @"operation";
CommandRequest *request2 = [[CommandRequest alloc] init];
request2.text = @"完成完成";
request2.type = @"reply";
NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:request1,request2, nil];
quickCreateRequest.commands = arr;
//quickCreateRequest.commands = @[@"关闭开关",@"停止播放音乐"];

[[[DCAManager shared] deviceManager] addSceneWithProductId:@"" quickCreateRequest:quickCreateRequest callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

8.13.2 删除场景模式

productId

产品Id

sceneId

创建场景模式时返回的指令Id

callBack

回调(状态码+msg)

[[[DCAManager shared] deviceManager] deleteSceneWithProductId:@"" sceneId:@"" callBack:^(NSString * errCode, NSString * msg) {

}];

8.13.3 更新场景模式

productId

产品Id

sceneId

创建场景模式时返回的指令Id

quickCreateRequest

quickCreateRequest

callBack

回调(状态码+msg+数据)

QuickCreateRequest *quickCreateRequest = [[QuickCreateRequest alloc] init];
quickCreateRequest.sentences = @[@"我下班了"];
CommandRequest *request1 = [[CommandRequest alloc] init];
request1.text = @"打开开关";
request1.type = @"operation";
CommandRequest *request2 = [[CommandRequest alloc] init];
request2.text = @"完成完成";
request2.type = @"reply";
NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:request1,request2, nil];
quickCreateRequest.commands = arr;
//quickCreateRequest.commands = @[@"打开开关",@"播放周杰伦的歌"];

[[[DCAManager shared] deviceManager] updateSceneWithProductId:@"" sceneId:@"" quickCreateRequest:quickCreateRequest callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

8.13.4 获取用户场景模式

productId

产品Id

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] deviceManager] getSceneWithProductId:@"" callBack:^(NSString * errCode, NSArray<InstructionModel *> * data) {

}];

9.技能相关接口

9.1 根据产品版本号查询内置技能列表  

productId

产品id

productVersion

产品版本号

callBack

回调(数据)

[[[DCAManager shared] skillManager] querySkillListByProductVersionWithProductId:@"" productVersion:@"" callBack:^(NSDictionary * data) {

}];

9.2 根据产品的分支号查询内置技能列表

productId

产品id

aliasKey

产品分支号,dui平台创建全链路产品的时候会有个分支号

callBack

回调(数据)

[[[DCAManager shared] skillManager] querySkillListByAliasKeyWithProductId:@"" aliasKey:@"" callBack:^(NSDictionary * data) {

}];

9.3 查询技能详情

skillId

技能id

skillVersion

技能版本号

callBack

回调(数据)

[[[DCAManager shared] skillManager] querySkillDetailWithSkillId:@"" skillVersion:@"" callBack:^(NSDictionary * data) {

}];

返回格式:

{
    "errcode":0,
    "errmsg":null,
    "data":[
        {
            "skillName":"天气家居",
            "image":"",
            "skillId":100000574,
            "utterances":"",
            "versionDesc":"",
            "skillDesc":"",
            "changeLog":"",
            "defaultLogo":8,
            "version":5
        }
    ]
}
skillId 技能id
version 技能版本
skillName 技能名称
skillDesc 技能描述
versionDesc 版本更新说明(指定到解决方案时填的)
changeLog 版本发布说明
utterances 推荐说法
defaultLogo

int型,每个值对应一张图片 默认logo,logo见工程demo中Resources.bundle目录

1: "ico_xiaolv.png",
2: "ico_life.png",
3: "ico_traffic.png",
4: "ico_movie.png",
5: "ico_social.png",
6: "ico_news.png",
7: "ico_quiz.png",
8: "ico_home.png",
9: "ico_car.png",
10: "ico_finance.png",
11: "ico_sports.png",
12: "ico_shopping.png",
13: "ico_game.png",
14: "ico_education.png"

image 用户上传的技能图标,优先取image,没有的话再取defaultLogo

9.4 批量查询技能详情

list

支持传多个技能列表id和version

callBack

回调(数据)

 

NSMutableArray <SkillDetailRequest *>*arr = [[NSMutableArray alloc] init];
SkillDetailRequest *request1 = [[SkillDetailRequest alloc] init];
request1.skillId = @"";
request1.skillVersion = @"";
[arr addObject:request1];
[[[DCAManager shared] skillManager] querySkillDetailsWithList:arr callBack:^(NSDictionary * data) {

}];

10.智能家居相关接口

10.1 查询智能家居技能

[[[DCAManager shared] smartHomeManager] querySmartHomeSkillWithCallBack:^(NSDictionary * data) {

}];

10.2 查询智能家居技能中的思必驰(自己的)账号和第三方智能家居平台账号的绑定状态

skillId

智能家居技能的id

skillVersion

智能家居技能的版本号

productId

产品id

callBack

回调(数据)

[[[DCAManager shared] smartHomeManager] querySmartHomeAccountStatusWithSkillId:@"" skillVersion:@"" productId:@"" callBack:^(NSDictionary * data) {

}];

10.3 获取某个第三方智能家居平台下的设备列表,前提是已经绑定过第三方智能家居平台账号了

skillId

智能家居技能的id(一个智能家居技能表示这个智能家居平台)

skillVersion

智能家居技能的版本号

productId

产品id

group

设备所属group,若为空,可填""

callBack

回调(数据)

[[[DCAManager shared] smartHomeManager] querySmartHomeApplianceWithSkillId:@"" skillVersion:@"" productId:@"" group:@"" callBack:^(NSDictionary * data) {

}];

10.4 获取所有第三方智能家居平台下的设备列表,前提是已经绑定过第三方智能家居平台账号了

productId

产品id

callBack

回调(数据)

[[[DCAManager shared] smartHomeManager] queryAllSmartHomeApplianceWithProductId:@"" callBack:^(NSDictionary * data) {

}];

10.5 查询智能家居第三方平台下的设备的位置信息

applianceId

智能家居平台的设备id

skillId

智能家居技能id

callBack

回调(数据)

[[[DCAManager shared] smartHomeManager] queryAppliancePositionWithApplianceId:@"" skillId:@"" callBack:^(NSDictionary * data) {

}];

10.6 更新第三方平台设备的自定义位置信息

applianceId

智能家居平台的设备id

skillId

智能家居技能id

productId

产品id

position

位置信息,比如客厅,仅支持中文,长度2-6

group

设备所属group,若为空,可填""

callBack

回调(数据)

[[[DCAManager shared] smartHomeManager] updateApplianceCustomPositionWithApplianceId:@"" skillId:@"" productId:@"" position:@"" group:@"" callBack:^(NSDictionary * data) {

}];

10.7 更新家居设备名字

applianceId

智能家居平台的设备id

skillId

智能家居技能id

productId

产品id

alias

要更新的名称,只支持中文,长度为2-6个,单个用户下仅支持最多50个自定义名称

group

设备所属group,若为空,可填""

callBack

回调(数据)

[[[DCAManager shared] smartHomeManager] updateApplianceAliasWithApplianceId:@"" skillId:@"" productId:@"" alias:@"" group:@"" callBack:^(NSDictionary * data) {

}];

10.8 主动同步用户账号下的设备名称和设备位置

目前限定自定义名称 :

1. 字符必须为汉字,英文字母(必须为大写字母)或者阿拉伯数字(最多 1 个)。

2. 如果有阿拉伯数字,则必须在词尾。

3. 字符(UTF-8)长度在 [2, 10] 内。

4. 整个语句不在敏感词列表中。

 

目前限定位置自定义位置:

1. 字符必须为汉字,英文字母(必须为大写字母)或者阿拉伯数字(最多 1 个)。

2. 如果有阿拉伯数字,则必须在词尾。

3. 字符(UTF-8)长度在 [2, 6] 内。

4. 整个语句不在敏感词列表中。

 

否则同步设备名称和位置会出现异常

注意:在调用了跳过智能家居页面接口或者在智能家居页面登录绑定后可以不用立刻调用该接口,否则会出错

因为在绑定过程中服务端默认会同步一次设备,而思必驰的同一用户的同步设备是单任务的

 

productId

产品id

group

可选参数,如果有可以调用,设备所属的group(必须与iotSkillId搭配使用,否则无效)

iotSkillId

用于限定group过滤的技能 ID

skillList

需要同步的设备list(同步所有家居技能列表时传nil)

callBack

回调(数据)

//示例:同步其中几个(如果需要同步所有的,skillList传nil即可)
NSMutableArray <ApplianceAliasSyncModel *>*mutArr = [[NSMutableArray alloc] init];
ApplianceAliasSyncModel *model1 = [ApplianceAliasSyncModel new];
model1.skillId = @"";
model1.skillVersion = @"";
[mutArr addObject:model1];
[[[DCAManager shared] smartHomeManager] applianceAliasSyncWithProductId:@"" group:@"" iotSkillId:@"" skillList:mutArr callBack:^(NSDictionary * data) {

}];

10.9 跳过智能家居技能登录页面

当集成本sdk的开发者和智能家居厂商是同一家公司的时候,这时候在app登录完成后,如果使用智能家居功能,还需要登录一次,那么这个体验会很差,如果需要跳过第二次智能家居平台的登录,则可以调用如下接口:

注意:skillid和skillversion一定要填写正确,不能瞎填。token一定要是和思必驰oauth对接后,思必驰服务端能使用该token访问贵司智能家居服务,智能家居技能务必要上架成功。

smartHomeTokenRequest

smartHomeTokenRequest

callBack

回调(数据)

SmartHomeTokenRequest *request = [[SmartHomeTokenRequest alloc] init];
request.skillId = @"";
request.skillVersion = @"";
request.productId = @"";
request.smartHomeAccessToken = @"";
request.smartHomeRefreshToken = @"";
request.accessTokenExpiresIn = 60;

[[[DCAManager shared] smartHomeManager] updateSmartHomeTokenInfoWithSmartHomeTokenRequest:request callBack:^(NSDictionary * data) {

}];
注:调这个接口需要上架家居技能,或者使用真机测试的productId,成功接口返回空串{}

PS:一旦更新某个用户的token(永久token),那么该用户历史设置的token立即失效,无法在其他接口中使用

10.10 绑定第三方智能家居账号,这个接口需要拦截webview的回调后调用,具体参考demo

url

拦截到的webview的回调地址

productId

产品id

skillVersion

智能家居技能版本

callBack

回调(数据)

[[[DCAManager shared] smartHomeManager] bindSmartHomeAccountWithUrl:@"" productId:@"" skillVersion:@"" callBack:^(NSDictionary * data) {

}];

10.11 解除绑定第三方智能家居账号

skillId

智能家居技能id

callBack

回调(数据)

[[[DCAManager shared] smartHomeManager] unbindSmartHomeAccountWithSkillId:@"" callBack:^(NSDictionary * data) {

}];

10.12 根据智能家居技能id获取详情

skillId

智能家居技能id

callBack

回调(数据)

 

[[[DCAManager shared] smartHomeManager] getSmartHomeDetailWithSkillId:@"" callBack:^(NSDictionary * data) {

}];

10.13 根据智能家居技能id查询该智能家居技能支持的设备

skillId

智能家居技能id

page

页数

pageSize

每页数量

callBack

回调(数据)

 

[[[DCAManager shared] smartHomeManager] getSupportDeviceWithSkillId:@"" page:1 pageSize:10 callBack:^(NSDictionary * data) {

}];

10.14 批量获取第三方平台智能家居账号绑定状态

productId

产品id

list

技能请求list

callBack

回调(数据)

NSMutableArray <SkillRequest *>*arr = [[NSMutableArray alloc] init];
SkillRequest *request = [[SkillRequest alloc] init];
request.skillId = @"";
request.skillVersion = @"";
[arr addObject:request];
[[[DCAManager shared] smartHomeManager] batchQuerySmartHomeAccountStatusWithProductId:@"" list:arr callBack:^(NSDictionary * data) {

}];

10.15 批量获取第三方智能家居平台的设备的自定义位置信息

注意:如果某个设备没有设置过位置信息,就不会返回该设备的数据

productId

产品id

list

技能id列表

callBack

回调(数据)

NSMutableArray <BatchPosRequest *>*arr = [[NSMutableArray alloc] init];
BatchPosRequest *request = [[BatchPosRequest alloc] init];
request.skillId = @"";
[arr addObject:request];
[[[DCAManager shared] smartHomeManager] batchQueryAppliancePositionWithProductId:@"" list:arr callBack:^(NSDictionary * data) {

}];

11.实时消息&播控

11.1 实时消息

11.1.1 连接MQTT服务

ConnectStatus状态说明

/// 设备连接状态
typedef SWIFT_ENUM(NSInteger, ConnectStatus, closed) {
/// 连接成功
  ConnectStatusCONNECT_SUCCESS = 1,
/// 连接失败
  ConnectStatusCONNECT_FAIL = 2,
/// 订阅成功
  ConnectStatusSUBSCRIBE_SUCCESS = 3,
/// 取消订阅成功
  ConnectStatusUNSUBSCRIBE_SUCCESS = 4,
};
//全局只需要连接一次,成功则无需重复调用此接口(成功后只需要调用订阅与取消订阅接口即可),连接失败SDK内部已做重连机制,无需自行处理重连
[[[DCAManager shared] deviceControlManager] connectWithConnectStatus:^(ConnectStatus status) {

}];

11.1.2 订阅主题

topic

主题

[[[DCAManager shared] deviceControlManager] subscribeTopicWithTopic:@""];

11.1.3 向某一个topic发送数据

topic

topic

jsonStr

json数据字符串

isRetain

是否为retain消息(根据与设备端约定的情况而定)

[[[DCAManager shared] deviceControlManager] sendDataWithTopic:@"" jsonStr:@"" isRetain:NO];

11.1.4 取消订阅主题

topic

主题

[[[DCAManager shared] deviceControlManager] unSubscribeTopicWithTopic:@""];

11.1.5 断开连接

//操作:连接成功后主动断开连接(一般情况下连接成功后无需主动断开连接,解绑设备或其他特殊情况只需取消订阅主题即可)
[[[DCAManager shared] deviceControlManager] disconnect];

11.1.6 实时消息

PlayStatus状态说明

/// 设备播放状态(播放DUI资源,上下首的时候,返回的是app_play且data里面包含了歌曲信息;播放自有资源的时候,上下首会有标识)
typedef SWIFT_ENUM(NSInteger, PlayStatus, closed) {
/// 其他情况
  PlayStatusAPP_OTHER_TYPE = -1,
/// 断线或者断电
  PlayStatusAPP_OFFLINE = 0,
/// 心跳
  PlayStatusAPP_ONLINE = 1,
/// 播放
  PlayStatusAPP_PLAY = 2,
/// 暂停
  PlayStatusAPP_SUSPEND = 3,
/// 继续播放
  PlayStatusAPP_CONTINUE_PLAY = 4,
/// 下一首
  PlayStatusAPP_NEXT = 5,
/// 上一首
  PlayStatusAPP_PREV = 6,
/// 音量
  PlayStatusAPP_SOUND = 7,
/// 下载
  PlayStatusAPP_DOWNLOAD_STATE = 8,
/// 播放模式(model取值范围:1.顺序播放,2.单曲播放)
  PlayStatusAPP_PLAY_MODE = 9,
/// 蓝牙下一首
  PlayStatusAPP_BLUETOOTH_NEXT = 10,
/// 蓝牙上一首
  PlayStatusAPP_BLUETOOTH_PREV = 11,
/// 蓝牙暂停
  PlayStatusAPP_BLUETOOTH_SUSPEND = 12,
/// 蓝牙继续播放
  PlayStatusAPP_BLUETOOTH_CONTINUE = 13,
/// 设备蓝牙开启或关闭
  PlayStatusAPP_BLUETOOTH = 14,
/// 播放进度
  PlayStatusAPP_DRAG = 15,
/// 设备解绑
  PlayStatusAPP_UNBIND = 16,
/// 设备播放歌曲状态
  PlayStatusAPP_STATE = 17,
/// 收藏
  PlayStatusAPP_LIKE = 18,
/// 取消收藏
  PlayStatusAPP_CANCEL_LIKE = 19,
};
//返回消息状态以及数据实体
[[[DCAManager shared] deviceControlManager] onReceiveControlMessageWithReceiveMessage:^(PlayStatus playStatus, NSDictionary *data) {


}];

11.2 播控

11.2.1 暂停播放

[[[DCAManager shared] deviceControlManager] pausePlayWithCallBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

11.2.2 继续播放

[[[DCAManager shared] deviceControlManager] continuePlayWithCallBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

11.2.3 播放上一首

[[[DCAManager shared] deviceControlManager] playPreviousMusicWithCallBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

11.2.4 播放下一首

[[[DCAManager shared] deviceControlManager] playNextMusicWithCallBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

11.2.5 获取播放列表

page

页数(没有指定page或page为0,取正在播放的歌曲所在页)

count

每页数量

callBack

回调(状态码+msg+当前播放页+总页数+数据)

[[[DCAManager shared] deviceControlManager] getPlayListWithPage:0 count:20 callBack:^(NSString * errCode, NSString * msg, NSInteger currentPlayPage, NSInteger totalPage, NSArray<ChildAlbumBrowseModel *> * data) {

}];

11.2.6 清空播放列表

[[[DCAManager shared] deviceControlManager] cleanPlayListWithCallBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

11.2.7 获取当前播放位置

[[[DCAManager shared] deviceControlManager] getCurrentPlayIndexWithCallBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

11.2.8 播放播放列表的某一首歌

sort

需要播放的某一首歌曲位置,对应ChildAlbumBrowseModel中的sort

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] deviceControlManager] playMusicFromPlayListWithSort:@"" callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

11.2.9 播放列表的某一首歌

注:客户如果是推送自有资源,需要将歌曲信息封装成ChildAlbumBrowseModel中的参数,并且将isOwn设置为NO

model

歌曲model

callBack

回调(状态码+msg+数据)

ChildAlbumBrowseModel *model = [[ChildAlbumBrowseModel alloc] init];//歌曲model
[[[DCAManager shared] deviceControlManager] playMuiscFromListWithModel:model callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

11.2.10 播放专辑列表的某一首歌

information

albumType

model

专辑model

index

专辑里面第几首歌

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] deviceControlManager] playMuiscFromAlbumListWithInformation:@"" model:albumModel index:1 callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

11.2.11 推送收藏歌曲成功后需调用的接口

推送收藏列表歌曲(调用12.2.9)成功后还需调用此接口,获取播放列表接口才会返回整个收藏列表,反之则只返回当前这一首歌

[[[DCAManager shared] deviceControlManager] playCollectionListWithCallBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

11.2.12 获取当前播放模式

[[[DCAManager shared] deviceControlManager] getCurrentPlayModelWithCallBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

11.2.13 设置播放模式

curmodel

播放模式(1.顺序播放,2.单曲播放,3.随机播放)

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] deviceControlManager] setPlayModelWithCurmodel:@"1" callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

11.2.14 获取音量

[[[DCAManager shared] deviceControlManager] getVolumeWithCallBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

11.2.15 设置音量

volume

音量

callBack

回调(状态码+msg+数据)

[[[DCAManager shared] deviceControlManager] setVolumeWithVolume:80 callBack:^(NSString * errCode, NSString * msg, NSDictionary * data) {

}];

12.人声复刻

用户可以复刻合成一个与用户相似的TTS音色,应用在特定的一些播报场景,提升语音交互的趣味性

12.1 获取tts复刻录音文本列表

[[[DCAManager shared] voiceCopyManager] getTextWithProductId:@"" callBack:^(NSString * _Nonnull errCode, NSString * _Nonnull msg, NSArray<VoiceCopyTextModel *> * _Nullable data) {
                
}];

12.2 上传音频(音频检测)

UploadRequestModel *request = [[UploadRequestModel alloc] init];
request.productId = @"";
request.textId = @"";
request.gender = @"MALE";
request.age = @"ADULT";
request.data = wavData;
[[[DCAManager shared] voiceCopyManager] uploadWithRequest:request callBack:^(NSDictionary * _Nullable data) {
                    
}];

12.3 提交训练

调用接口时,现在平台的要求是每个句子的得分不能低于70分,否则无法得到复刻的声音。

TrainRequestModel *request = [[TrainRequestModel alloc] init];
request.productId = @"";
request.gender = @"MALE";
request.age = @"ADULT";
request.customInfo = @"";
request.audio_list = @[];
request.pre_tts_text = @[];
[[[DCAManager shared] voiceCopyManager] trainingWithRequest:request callBack:^(NSDictionary * _Nullable data) {
         
}];

12.4 查询该用户下训练任务的状态

[[[DCAManager shared] voiceCopyManager] queryTaskWithProductId:@"" callBack:^(NSDictionary * _Nullable data) {

}];

12.5 删除音色

DeleteRequestModel *request = [[DeleteRequestModel alloc] init];
request.productId = @"";
request.taskId = @"";
[[[DCAManager shared] voiceCopyManager] deleteToneWithRequest:request callBack:^(NSDictionary * _Nullable data) {

}];

12.6 更新音色名字

[[[DCAManager shared] voiceCopyManager] updateCustomInfoWithProductId:@"" taskId:@"" customInfo:@"" callBack:^(NSDictionary * _Nullable data) {

}];

在任务训练完成后,可以查询到该任务对应的音色的voiceId,后续在请求云端合成的时候可以将speaker设置为该voiceId,请求的服务端地址设置为http://tts.duiopen.com/api/v1/voicecopy/synthesize

云端合成出的声音就是该voiceId对应的复刻出的声音

13.H5集成

H5界面类型:

@objc public enum DCASDKEBTYPE:Int {

    /// 智能家居
    case SMARTHOME = 0

    /// 智能家居设备列表
    case SMARTHOME_DEVICE_LIST = 1

    /// 对话日志
    case DIALOG_MESSGAE = 2

    /// 技能中心
    case SKILL_CENTER = 3

    /// 产品内置技能
    case PRODUCT_SKILL = 4

    /// 搜索技能结果页
    case SEARCH_SKILL = 5

    /// 通用跳转页面
    case COMMON_PAGE = 6

    /// 已购技能
    case SKILL_INSTALL = 7

    /// 自定义问答
    case CUSTOME_DIALOG = 8

    /// 创建自定义问答
    case CUSTOME_DIALOGCREATE = 9

    /// 技能商店(兼容旧版本)
    case SKILL_STORE = 10
}


示例:直接将DCASDKWebViewController作为子控制器加载到贵司APP需要展示的控制器之上

- (void)viewDidLoad {

    [super viewDidLoad];
    // Do any additional setup after loading the view.

    self.view.backgroundColor = UIColor.whiteColor;
    DCASDKWebViewController *vc = [[DCASDKWebViewController alloc] init];
    vc.delegate = self;
    DCAWebViewInfo *webInfo = [[DCAWebViewInfo alloc] init];
    webInfo.productId = @"";//必需
    webInfo.deviceId = [[DCAManager shared] deviceId];//必需
    webInfo.productVersion = @"-1";//必需,默认参数为"-1"
    webInfo.webType = self.type;//必需,界面类型DCASDKEBTYPE
    webInfo.aliasKey = @"prod";//必需,默认参数为"prod"
    webInfo.manufacture = @"";必需
    webInfo.searchContent = @"";//当webType为SEARCH_SKILL(搜索技能结果页类型)时,必需
    webInfo.isHiddenTitle = YES;//非必需,是否隐藏H5的导航栏,默认为不隐藏
    webInfo.isUseCustomWebViewFrame = YES;//非必需,是否自定义webView的frame,默认为NO
    webInfo.webViewFrame = CGRectMake(0, 0, 0, 0));//非必需,如果isUseCustomWebViewFrame设置为YES,可设置自己需要的webView的frame
    vc.webInfo = webInfo;
    vc.view.frame = CGRectMake(0, 0, 0, 0));//设置DCASDKWebViewController控制器view的frame
    [self.view addSubview:vc.view];
    [self addChildViewController:vc];
    [vc loadH5];
    self.webVC = vc;
}


#pragma mark - DCASDKWebViewControllerDelegate


//H5的title改变回调
-(void)onTitleChangeWithTitle:(NSString *)title {
    NSLog(@"%@",title);
    self.title = title;
}


//点击技能回调需要进入的详情url,CommonWebVC中webInfo.webType需设置为DCAWEBTYPECOMMON_PAGE,具体可参考demo
-(void)webViewOpenNewTabWithParam:(NSString *)param {

    NSLog(@"%@",param);
    CommonWebVC *webVC = [[CommonWebVC alloc] init];
    webVC.urlStr = param;
    [self.navigationController pushViewController:webVC animated:true];
}

14.常见错误码

-10000  接口请求出错

103658  微信登录,未关联手机号

103634  验证码已过期

103660  手机号已被关联过

108900  服务器内部错误

108901  服务器内部错误

108902  服务器内部错误

108903  传参出错

108904  账号互通接口,第三方token无效

108905  服务器内部错误

108906  传参出错

108907  服务器内部错误

108908  思必驰用户id和思必驰账号的token不匹配

108909  设备(音箱)绑定出错

108910  服务器内部错误

108911  服务器内部错误

108912  查询第三方智能家居厂商设备超时

103108  不合法的dca token,需要刷新dca token

103601  dca token已过期,需要刷新dca token

103602  dca记住我凭证不合法,需要重新登录dca 账号

15.FAQ

问题 注意事项
SDK接口无法调用成功且返回鉴权失败 检查SDK是否进行init操作(init贵司项目经向我司申请appKey和secret参数)
SDK调用接口时一直进入onNeedLogin代理方法

1、SDK需先进行登录再进行使用(可调用文档第4章节api接口,如使用我司账号系统可调用4.1接口;如贵司有自有账号系统,可调用4.2接口);

2、如使用的4.2接口,且接口返回错误token校验失败,先确认manufactureSecret参数是否正确,再确认贵司提供的校验接口是否能验证通过。

设备配网失败

1、先使用提供的demo进行配网验证是否能够正常配网;

2、检查网络是否可用;

3、检查设备固件是否为最新版本(如设备端是基于SDK进行开发,先与我司设备端进行沟通,确定配网流程是否正确);

4、如SDK配网接口60s后返回配网超时失败,但设备又提示配网成功,找设备端进行确认是否有上报配网成功消息;

5、设备配网成功,但是无法正常唤醒,确认设备是否授权成功。

无法搜索到蓝牙设备 结束蓝牙配网后需进行dealloc操作,否则下次进入重新再次init会搜索不到设备
使用移动网络的宽带或者手机热点的时候配网不成功 先咨询设备端是否为最新SDK,设备端最新SDK已解决此问题(由于移动劫持了ip地址为114.114.114.114的访问,导致设备无法正常连接网络)
如何拿到设备授权时候的codeVerifier

codeVerifier需要在获取authCode接口(requestAuthCode)调用成功后才能正确拿到

H5界面显示空白界面 参数必须按照文档上标注的来进行传递(必填项不能不传,且必须保证参数的准确性),aliasKey参数请根据贵司在DUI平台上建立的分支来进行填写
在成功绑定了第三方智能家居平台账号后,H5界面显示错误 第三方智能家居账号只能由一个用户进行使用,如果多人同时使用同一个账号,会导致第三方账号的refreshToken失效,从而导致我们的H5界面显示错误
解绑接口缺少设备唯一标识,如何解绑 SDK内部对deviceId进行了全局处理,不过需在“绑定设备”或者“多个设备的情况下切换至当前选中设备”的时候需要先进行赋值操作,详细可查看文档3.4章节第5点和8.1
如何保证SDK的token有效期 本质上用户不需要关心SDK内部的token有效期,SDK在token失效之后有自主刷新机制,如果刷新token失败,此时会走到onNeedLogin代理方法,在方法里需要进行重新登录操作(4.1.2或者4.2)
实时消息和播控的区别

设备与APP之间的双向操作

1、实时消息:对设备端进行操作,此时会通过MQTT返回的消息给到APP,APP再在拿到消息之后去进行相对应的显示或者操作

2、播控:APP通过调用http接口去控制设备端做不同的操作响应

绑定多个设备的时候,且均配网成功且同时在线的时候,收到的MQTT消息错乱

1、切换设备时,deviceId一定要记得重新赋值;

2、在deviceId重新赋值之前,先取消上一个设备MQTT的topic订阅,再订阅下一个设备的topic,SDK目前播控操作方面上只支持订阅一个topic

无法获取第三方智能家居平台的设备自定义位置信息 如果设备没有设置过位置信息,就不会获取到相关位置数据,获取到的前提是进行过设置自定义位置的操作

跳过智能家居技能登录界面接口返回参数为[:]

此接口不报错误码,接口有值就说明调用成功,判断返回的data是否为nil即可
使用SDK时因为UIWebView原因被拒 使用最新版本,SDK已全面升级为WKWebView