自有App接入天猫精灵教程

生活物联网平台提供了免费的天猫精灵快捷通道。您的产品只需定义了平台的标准功能属性,且在天猫精灵支持的品类中,在完成相应的配置后,即可快速连接天猫精灵,实现天猫精灵音箱对设备的控制。

限制条件

  • 生活物联网平台遵循ICA数据标准,为了确保您的设备可以被天猫精灵准确识别和控制,请确保使用标准功能。

  • 仅支持在中国境内激活的设备对接天猫精灵。

消费者使用

阿里IoT的公版免开发App支持天猫精灵控制,使用方式如下步骤所示。

  1. 用户拥有一台支持天猫精灵的设备,下载厂家自有品牌App,绑定该设备。

  2. 用户拥有一台天猫精灵音箱,从手机端应用商店下载天猫精灵App并绑定该音箱。

  3. 在厂家自有品牌App中,用户授权淘宝账号登录,成功绑定天猫精灵。

    说明

    App账号和淘宝账号是一一对应的。

  4. 用户在天猫精灵App的设备列表中,在我家页签中可以看到绑定的设备。天猫精灵控制设备

  5. 完成以上步骤后,您可以通过天猫精灵音箱控制您的设备。

控制台开通

  1. 确认已打开天猫精灵的控制开关。

    1. 选择一个现有的项目,或创建一个新项目。参见创建项目

    2. 创建一个新产品,参见创建产品

    3. 定义产品的功能,参见定义产品功能

    4. 添加测试设备,参见设备开发与调试

    5. 配置语音交互,详情请参见配置人机交互

      当选择交互端为云智能App时,可以开启语音交互>天猫精灵>控制口令的按钮,接入天猫精灵语音,使用天猫精灵音箱进行语音控制设备。image.png

  2. 调试设备。

    使用云智能App配网绑定了您的测试设备后,可以根据下方消费者使用步骤,绑定天猫精灵,即可实现音箱的控制。下载云智能App请参见云智能App介绍

    重要

    首次注册账号时,国家和地区请选择中国内地

  3. 创建一个自有App,参见创建自有App

开发Android自有App

由于天猫精灵使用淘宝账号体系,需要在您的自有品牌App中,集成淘宝的账号授权,从而实现和天猫精灵的对接。

  1. 调用淘宝登录授权页面的唤起接口。

    开发步骤如下图所示。调用接口流程

  2. 单击授权按钮,进入授权界面。

    加载WebView,授权网址URL如下(需要拼接AppKey)。

    String url = "https://oauth.taobao.com/authorize?response_type=code&client_id=<项目的appKey>&redirect_uri=<控制台定义的回调地址>&view=wap";
  3. 在shouldOverrideUrlLoading中判断地址是否包含code,获取code并传到上一步访问URL后的界面。

    mWebView.setWebViewClient(new WebViewClient() {
                //设置结束加载函数
                @Override
                public void onPageFinished(WebView view, String url) {
                    topbar.setTitle(view.getTitle());
                }
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    if (isTokenUrl(url)) {
                        Intent intent = new Intent();
                        intent.putExtra("AuthCode", mAuthCode);
                        setResult(RESULT_CODE, intent);
                        finish();
                        return true;
                    }
                    view.loadUrl(url);
                    return false;
                }
            });
    
      private boolean isTokenUrl(String url) {
            if (!TextUtils.isEmpty(url)) {
                if ( url.contains("code=")) {
                    String[] urlArray = url.split("code=");
                    if (urlArray.length > 1) {
                        String[] paramArray = urlArray[1].split("&");
                        if (paramArray.length > 1) {
                            mAuthCode = paramArray[0];
                            return true;
                        }
                    }
                }
            }
            return false;
        }
  4. 根据code绑定淘宝账号。

    示例代码如下,其中/account/taobao/bind接口的说明,请参见账号服务

    public void bindAccount(String authCode) {
    
            JSONObject params = new JSONObject();
            if (null != authCode) {
                params.put("authCode", authCode);
            }
            Map<String, Object> requestMap = params.getInnerMap();
    
            IoTRequest ioTRequest = new IoTRequestBuilder()
                    .setAuthType("iotAuth")
                    .setApiVersion("1.0.5")
                    .setPath("/account/taobao/bind")
                    .setParams(requestMap)
                    .setScheme(Scheme.HTTPS)
                    .build();
            new IoTAPIClientFactory().getClient().send(ioTRequest, new IoTCallback() {
                @Override
                public void onFailure(IoTRequest ioTRequest, Exception e) {
    
                }
    
                @Override
                public void onResponse(IoTRequest ioTRequest, IoTResponse ioTResponse) {
    
                }
            });
        }
  5. (可选)调用接口解除绑定。

    // 用户解绑淘宝Id
    IoTRequestBuilder builder = new IoTRequestBuilder();
    builder.setPath("/account/thirdparty/unbind");
    builder.setApiVersion("1.0.5");
    builder.setAuthType("iotAuth");
    builder.addParam("accountType","TAOBAO");
    
    IoTRequest ioTRequest = builder.build();
    new IoTAPIClientFactory().getClient().send(ioTRequest, new IoTCallback() {
        @Override
        public void onFailure(IoTRequest ioTRequest, final Exception e) {}
        @Override
        public void onResponse(IoTRequest ioTRequest, final IoTResponse ioTResponse) {}
    });
    ///account/thirdparty/unbind接口的说明,请参见账号服务
    //此处para = @{@"accountType":@"TAOBAO"}
  6. 判断是否已绑定。

    /account/thirdparty/get接口的说明,请参见账号服务

    // 查询当前用户绑定淘宝Id
    IoTRequestBuilder builder = new IoTRequestBuilder();
    builder.setPath("/account/thirdparty/get");
    builder.setApiVersion("1.0.5");
    builder.setAuthType("iotAuth");
    builder.addParam("accountType","TAOBAO");
    
    IoTRequest ioTRequest = builder.build();
    new IoTAPIClientFactory().getClient().send(ioTRequest, new IoTCallback() {
        @Override
        public void onFailure(IoTRequest ioTRequest, final Exception e) {}
        @Override
        public void onResponse(IoTRequest ioTRequest, final IoTResponse ioTResponse) {}
    });

开发iOS自有App

由于天猫精灵使用淘宝账号体系,需要在您的自有品牌App中,集成淘宝的账号授权,从而实现和天猫精灵的对接。

  1. 调用淘宝登录授权页面的唤起接口。

    开发步骤如下图所示。调用接口流程

  2. 单击授权按钮,进入授权界面。

    加载WebView,授权网址URL如下(需要拼接AppKey)。

    https://oauth.taobao.com/authorize?response_type=code&client_id=<项目的appKey>&redirect_uri=<控制台定义的回调地址>&view=wap

    初始化一个WebView,并设置代理加载。示例代码如下。

    - (void)viewDidLoad {
        [super viewDidLoad];
        [super viewDidLoad];
      WKWebView *webView = [[WKWebView alloc]init];
      [self.view addSubview:webView];
      [webView mas_makeConstraints:^(MASConstraintMaker *make) {
          make.left.equalTo(self.view);
          make.right.equalTo(self.view);
          make.top.equalTo(self.view);
          make.bottom.equalTo(self.view);
        }];
      webView.navigationDelegate = self; //代理:WKNavigationDelegate
      [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://oauth.taobao.com/authorize?response_type=code&client_id=%@&redirect_uri=控制台定义的回调地址&view=wap", 项目的appkey]]]];
    }
  3. 加载页面成功后,使用真实的淘宝账号登录。

    淘宝账号登录

  4. 登录成功后,处理您在控制台填写的回调地址。

    回调地址

    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    
        NSRange range = [navigationAction.request.URL.absoluteString rangeOfString:@"控制台定义的回调地址"];
        if (range.location){
            //允许跳转
            decisionHandler(WKNavigationActionPolicyAllow);
        } else {
            //不允许跳转
            decisionHandler(WKNavigationActionPolicyCancel);
            NSURLComponents *components = [NSURLComponents componentsWithString:navigationAction.request.URL.absoluteString];
    
            for (NSURLQueryItem *item in components.queryItems){
                if ([item.name isEqualToString:@"code"]){
                    //用户绑定淘宝ID请求:此处IMSTmallSpeakerApi 通过下面代码封装一个基础请求类
                    [IMSTmallSpeakerApi bindTaobaoIdWithParams:@{@"authCode":item.value} completion:^(NSError *err, NSDictionary *result) {
    
                        if (self.completion){
                            self.completion(err, result);
                        }
                        [self.navigationController popViewControllerAnimated:YES];
                    }];
                    break;
                }
            }
        }
    }
    
    // 封装的IMSTmallSpeakerApi请求类,依赖请求类#import <IMSApiClient/IMSApiClient.h>
    // .h中
    + (void)requestTmallSpeakerApi:(NSString *)api
                           version:(NSString *)ver
                            params:(NSDictionary *)para
                        completion:(void (^)(NSError *, id))completion;
    
    // .m中
    + (void)requestTmallSpeakerApi:(NSString *)api
                           version:(NSString *)ver
                            params:(NSDictionary *)para
                        completion:(void (^)(NSError *, id))completion {
    
        IMSIoTRequestBuilder *builder = [[IMSIoTRequestBuilder alloc] initWithPath:api
                                                                        apiVersion:ver
                                                                            params:para];
        [builder setScheme:@"https"];
    
        IMSRequest *request = [[builder setAuthenticationType:IMSAuthenticationTypeIoT] build];
        [IMSRequestClient asyncSendRequest:request responseHandler:^(NSError * _Nullable error, IMSResponse * _Nullable response) {
            if (completion) {
                //返回请求过期后,需要重新登录;重新登录后重新初始化主框架,不需要重新请求
                if (response.code == 401) {
                    if (NSClassFromString(@"IMSAccountService") != nil) {
                        // 先退出登录
                        if ([[IMSAccountService sharedService] isLogin]) {
                            [[IMSAccountService sharedService] logout];
                        }
                        return;
                    }
                }
    
                if (!error && response.code == 200) {
                    completion(error, response.data);
                    return ;
                }
    
                NSError *bError = [NSError errorWithDomain:NSURLErrorDomain
                                                      code:response.code
                                                  userInfo:@{NSLocalizedDescriptionKey: response.localizedMsg ? : @"服务器应答错误"}];
                completion(bError, nil);
                return;
            }
        }];
    }
    // 用户绑定淘宝Id
    + (void)bindTaobaoIdWithParams:(NSDictionary *)para
                        completion:(void (^)(NSError *, NSDictionary *))completion{
        [self requestTmallSpeakerApi:@"/account/taobao/bind" version:@"1.0.5" params:para completion:completion];
    ///account/taobao/bind接口说明请参见账号服务
    }
    //此处para = @{@"authCode":@"xxxx"},其中xxxx为网页回调的code,具体查看登录成功后的回调处理步骤

    处理回调后返回code200,表示授权成功。此时请刷新网页。

  5. (可选)调用接口解除绑定。

    // 用户解绑淘宝Id
    + (void)unbindTaobaoIdWithParams:(NSDictionary *)para
                          completion:(void (^)(NSError *, NSDictionary *))completion{
        [self requestTmallSpeakerApi:@"/account/thirdparty/unbind" version:@"1.0.5" params:para completion:completion];
    }
    ///account/thirdparty/unbind接口的说明,请参见账号服务
    //此处para = @{@"accountType":@"TAOBAO"}
  6. 判断是否已绑定。

    /account/thirdparty/get接口的说明,请参见账号服务

    // 查询用户绑定的淘宝Id
    + (void)getTaobaoIdWithParams:(NSDictionary *)para
                       completion:(void (^)(NSError *, NSDictionary *))completion{
        [self requestTmallSpeakerApi:@"/account/thirdparty/get" version:@"1.0.5" params:para completion:completion];
    }
    //此处para = @{@"accountType":@"TAOBAO"}

    返回数据存在以下内容代表已绑定。

    {
        accountId = 90xxx335;
        accountType = TAOBAO;
        linkIndentityId = 50ebop9xxxxxxxxxxxxxx8dbc58643423092968;
    }