语音技能 UI 业务包

更新时间:2023-07-13 07:14:38下载pdf

涂鸦语音技能 UI 业务包(简称技能 UI 业务包) 提供一键快速绑定 Amazon Alexa 和 Google Assistant 的自定义语音技能服务。该 UI 业务包暂无依赖服务。

准备工作

集成之前,请先完成以下准备工作:

  1. 在集成之前,请参考 框架接入 先熟悉 UI 业务包的准备工作和接入流程。

    请确保在您的主工程目录下,已经添加了 thing_custom_config.json 文件,后续 Google assistant 快速绑定需要在其中有相关配置。

  2. 对于技能快速绑定,请先在涂鸦增值服务开通对应的技能快绑服务,例如 Amazon Alexa 技能绑定服务开通Google Assistant 技能绑定服务开通

  3. 在应用项目工程中 Signing & CapabilitiesAssociated Domains 添加 Universal Link,配置如下三个通用链接:

    applinks:<渠道标识符>.applink.smart321.com
    applinks:<渠道标识符>.applink.app.tuya.com
    applinks:<渠道标识符>.applink.appflip.tuya.com
    

    然后在 苹果开发者平台 证书注意开启 Associated Domains

  4. 在苹果开发者平台证书开启 Associated Domains 后,请在 涂鸦 IoT 开发平台 可选配置 > 证书配置 中上传 Distribution 的证书和描述文件。

Amazon Alexa 配置

跳转 Alexa App 授权之前,需要配置对应的白名单。

  • 在项目的 info.plist 中添加 LSApplicationQueriesSchemes,类型为 Array。
  • LSApplicationQueriesSchemes 中添加一个 item,类型为 String,值为 Alexa
  • 确保 LSApplicationQueriesSchemes 中所配置的 item 总数不超过 50 个。

Google Assistant 配置

在开通 Google Assistant 技能绑定服务 服务后,跟涂鸦对接人员索要 google_flip_client_id,并将其提供的 google_flip_client_id 填入 thing_custom_config.json 文件中。

{
    "config": {
        "google_flip_client_id": "您的 google_flip_client_id",
    },
}

接入组件

在工程的 Podfile 文件中,添加 UI 业务包组件,并执行 pod update 命令:

source "https://github.com/tuya/tuya-private-specs"
source 'https://cdn.cocoapods.org/'
platform :ios, '11.0'

target 'your_target_name' do
  # 添加技能 UI 业务包
  pod 'ThingSmartSkillQuickBindBizBundle'
end

服务协议

技能 UI 业务包实现 ThingValueAddedServiceProtocol 协议以提供对外服务,在 ThingModuleServices 组件中查看 ThingValueAddedServiceProtocol.h 协议文件内容为:

#import <Foundation/Foundation.h>
@protocol ThingValueAddedServiceProtocol <NSObject>

/**
 * jump to Amazon link home page
 * @params success callback
 * @params failure callback
 */
- (void)goToAmazonAlexaLinkViewControllerSuccess:(successBoolBlock)success failure:(failureBlock)failure;

/**
 * jump to Google link home page
 * @params success callback
 * @params failure callback
 */
- (void)goToGoogleAssitantLinkViewControllerSuccess:(successBoolBlock)success failure:(failureBlock)failure;

/// Call it inside method application:continueUserActivity:restorationHandler: in Appdelegate.m
- (BOOL)thing_application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^ __nonnull)(NSArray<id<UIUserActivityRestoring>> * __nullable restorableObjects))restorationHandler API_AVAILABLE(ios(8.0));

/**
 * 获取第三方的 绑定的数据
 * @param result 是数组
 * @param failure 回调
 */
- (void)getAllThirdPartyVoiceBindingStatus:(void (^_Nullable)(id _Nullable result))success failure:(failureBlock _Nullable )failure;

/**
 * 通过 getAllThirdPartyVoiceBindingStatus 这个接口获取 绑定的数据列表,并传递某一个数据 给 statusData,进行解绑操作
 * @param statusData 参数
 */
- (void)goToDeactiveViewController:(NSDictionary *_Nullable)statusData;

@end

注意事项

  • 调用任何接口前,务必确认用户已登录。
  • 必须在 Appdelegate 的 application:continueUserActivity:restorationHandler: 方法内实现 thing_application:continueUserActivity:restorationHandler:,否则无法处理 App 跳转的回调。

技能绑定

Objective-C 示例

#import <ThingSmartBizCore/ThingSmartBizCore.h>
#import <ThingModuleServices/ThingValueAddedServiceProtocol.h>

id<ThingValueAddedServiceProtocol> impl = [[ThingSmartBizCore sharedInstance] serviceOfProtocol:@protocol(ThingValueAddedServiceProtocol)];

// 跳转到 Alexa 快绑页面
[impl goToAmazonAlexaLinkViewControllerSuccess:^(BOOL result) {
    // 可以做 loading 操作
} failure:^(NSError * _Nonnull error) {
    // 可以做 loading 操作
}];

// 跳转到 Google Assistant 快绑页面
[impl goToGoogleAssitantLinkViewControllerSuccess:^(BOOL result) {
    // 可以做 loading 操作
} failure:^(NSError * _Nonnull error) {
    // 可以做 loading 操作
}];

AppDelegate.m
// 处理 App 跳转的回调
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
    id<ThingValueAddedServiceProtocol> impl = [[ThingSmartBizCore sharedInstance] serviceOfProtocol:@protocol(ThingValueAddedServiceProtocol)];
    return [impl thing_application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
}

Swift 示例

let impl = ThingSmartBizCore.sharedInstance().service(of: ThingValueAddedServiceProtocol.self)

// 跳转到 Alexa 快绑页面
(impl as AnyObject).go?(toAmazonAlexaLinkViewControllerSuccess: { (result) in
    // 可做 loading 操作
}, failure: { (error) in
    // 可做 loading 操作
})

// 跳转到 Google Assistant 快绑页面
(impl as AnyObject).go?(toGoogleAssitantLinkViewControllerSuccess: { (result) in
    // 可做 loading 操作
}, failure: { (error) in
    // 可做 loading 操作
})

// 处理 App 跳转的回调
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
                let impl = thingSmartBizCore.sharedInstance().service(of: ThingValueAddedServiceProtocol.self)
        return (impl as AnyObject).thing_application?(application, continue: userActivity, restorationHandler: restorationHandler) ?? true
}

技能解绑

Objective-C 示例

#import <ThingSmartBizCore/ThingSmartBizCore.h>
#import <ThingModuleServices/ThingValueAddedServiceProtocol.h>

id<ThingValueAddedServiceProtocol> impl = [[ThingSmartBizCore sharedInstance] serviceOfProtocol:@protocol(ThingValueAddedServiceProtocol)];
__weak typeof(impl) weakImpl = impl;
// 1. 拿到 已经绑定的 数组 数据
[impl getAllThirdPartyVoiceBindingStatus:^(NSArray *array) {
    if ([array isKindOfClass:[NSArray class]] && array.count > 0) {
        NSDictionary * dic = array.firstObject;
        // 2. 触发解绑
        [weakImpl goToDeactiveViewController:dic];
    }
} failure:^(NSError *error) {

}];

Swift 示例

不要使用 as 方式 let impl: ThingValueAddedServiceProtocol = ThingSmartBizCore.sharedInstance().service(of: ThingValueAddedServiceProtocol.self) as! ThingValueAddedServiceProtocol ,否则 impl 是 nil。请使用以下调用方式。

let impl = ThingSmartBizCore.sharedInstance().service(of: ThingValueAddedServiceProtocol.self);
// 1. 拿到 已经绑定的 数组 数据
(impl as AnyObject).getAllThirdPartyVoiceBindingStatus?({ (list :Any?) in
    if let array :Array = list as? Array<Any> {
        print("test",array);
        // 2. 触发解绑
        let first = array.first;
        (impl as AnyObject).go?(toDeactiveViewController: first as? [AnyHashable : Any]);
    }
}, failure: { (error: Error?) in

})

测试步骤

请参考《帮助中心》如何测试 Alexa 和 Google 快速绑定功能