一、背景及大纲介绍
在物联网大行其道的今天,万物互联已经是趋势。通过App控制智能设备,且能够实现场景联动,已经不是做不做的选择题,而是破局企业端到端解决方案的关键。
智能硬件厂家如雨后春笋般涌现,但是,物联网的大框架—DCM(Device、Connect、Manage)架构,让IoT App成为刚需。智能硬件需要和App去结合,才能更好地发挥它的作用,更加便利人们的生活。如使用App去控制灯光的亮度,调节空调的温度,远程通过IPC监控家里情况等,甚至还可以使家里的相关电器完成一个场景联动(如手机设置“回家场景”,在下班回家的时候,点击“回家场景”,一键开灯、水壶烧水、空调开始工作等等)。这些原本只存在于想象中的场景,如今通过手机App+智能硬件即可实现。
但是,对于大部分企业而言,IoT App开发不仅新,而且充满挑战。
今天抽空以基于App SDK完成智能家居App的开发为例。通过这一篇文章,你就能通过创建App SDK、集成SDK、创建家庭、设备配网和设备控制等步骤,完整地完成一款智能家居App的开发。
先列一下开发大纲:
- 创建App SDK
- 集成SDK
- 注册和登录
- 创建家庭
- 设备配网
- 设备控制
我们再来简单介绍一下Tuya App SDK:
涂鸦智能 App SDK 专为 IoT 移动 App 开发打造,提供丰富组件和示例代码,开发者可以快速实现移动 App 对智能设备的连接、控制以及丰富的智能场景应用。
产品的优势在于:
- 低门槛快速集成:快速集成 SDK,提供示例代码、Demo App、接入案例等,低门槛轻松上手;
- 开发组件丰富:组件化开发,提供垂直品类 SDK、UI 业务包等功能组件,开发者根据需求灵活组合;
- 智能功能全面:全面覆盖用户、设备、智能场景等多种功能模块,开发者只需简单实现 UI 层代码;
- 主流通信协议兼容:同一 App 中支持添加和使用主流通信协议产品,轻松实现 All In One – App;
- 全球数据安全保障:双通道安全加密,五重安全策略,全球数据安全合规认证,全面保障用户数据隐私安全;
- 全球服务稳定:全球化智能云部署,让每一个 App 都轻松拥有亿级海量设备和千万级用户并发处理能力。
App SDK的技术架构如下:

二、如何基于 App SDK 开发一个 App
准备就绪,我们来开始开发!
(一)创建App SDK
1. 注册开发者账号
前往 涂鸦智能开发平台 注册开发者账号、创建产品、创建功能点等,具体流程请参考接入流程
2. 创建SDK应用
在涂鸦 IoT 平台中 “App 工作台” 中点击 “App SDK”,点击“创建 App”。

3. 填写 App 相关信息,点击确认。
-  应用名称:填写你的 App 名称。 
-  iOS 应用包名:填写你的 iOS App 包名(建议格式:com.xxxxx.xxxxx)。 
-  安卓应用包名:填写你的安卓 App 包名(两者可以保持一致,也可以不一致)。 
-  渠道标识符:不是必填项,如果不填写,系统会根据包名自动生成。 

你可以根据实际需求选择需要的选择方案,支持多选,然后根据 Podfile 和 Gradle 进行 SDK 的集成。

点击获取密码,获取 SDK 的 AppKey,AppSecret,安全图片等信息。

(二)集成 SDK
1. 使用 CocoaPods 快速集成
请注意:SDK 最低支持系统版本 9.0
在 Podfile 文件中添加以下内容:
  
   - 
    
     
    
    
     
      platform 
      :ios, 
      '9.0'
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      target 
      'Your_Project_Name' 
      do
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          pod 
      "TuyaSmartHomeKit"
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      end
     
    
然后在项目根目录下执行 `pod update` 命令进行集成。
2. 初始化 SDK
1) 打开项目设置,Target => General,修改 Bundle Identifier 为涂鸦开发者平台对应的 iOS 包名
2) 导入安全图片到工程根目录,重命名为 t_s.bmp,并加入「项目设置 => Target => Build Phases => Copy Bundle Resources」中。
3) 在项目的PrefixHeader.pch文件添加以下内容:
#import <TuyaSmartHomeKit/TuyaSmartKit.h>4) 打开AppDelegate.m文件,在[AppDelegate application:didFinishLaunchingWithOptions:]方法中初始化SDK。
接口说明
初始化 SDK
- (void)startWithAppKey:(NSString *)appKey secretKey:(NSString *)secretKey;参数说明

实例代码
[[TuyaSmartSDK sharedInstance] startWithAppKey:<#your_app_key#> secretKey:<#your_secret_key#>];3. 打开 Debug 模式
在开发的过程中可以开启 Debug 模式,打印一些日志用于分析问题,开发结束上线后建议关闭。
  
   - 
    
     
    
    
     
      #ifdef DEBUG
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [[TuyaSmartSDK sharedInstance] setDebugMode:
      YES];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      #else
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      #endif
     
    
(三)注册和登录
涂鸦云支持多种用户体系:手机、邮箱、UID。其中手机支持验证码登录和密码登录两种方式,UID 登录主要用于已经有自己账号体系的场景。我们这里采用手机验证码注册登录。

在注册登录方法中,需要提供 countryCode 参数(国家区号),用于就近选择涂鸦云的可用区。各个可用区的数据是相互独立的,因此在 中国大陆(86) 注册的账号,在 美国(1) 无法使用(用户不存在)。
1. 手机密码注册
手机号密码注册流程分为以下两步: 获取手机验证码 - 注册账号
  
   - 
    
     
    
    
     
      // 发送验证码   
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      [[
      TuyaSmartUser sharedInstance] sendVerifyCode:@
      "86" phoneNumber:@
      "1300****" 
      type:1 success:^{
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
          [TPDemoProgressUtils showSuccess:@"Verification code sent successfully" toView:nil];
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
      } failure:^(NSError *error) {
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
          [TPDemoProgressUtils showError:error.localizedDescription];
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
      }];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 通过验证码注册账号
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      [[
      TuyaSmartUser sharedInstance] registerByPhone:@
      "86" phoneNumber:@
      "1300****" password:@
      "***" code:@
      "code" success:^{
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          // 注册成功,跳转到首页
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [[
      TYDemoApplicationImpl sharedInstance] resetRootViewController:[
      TYDemoTabBarViewController 
      class]];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      } failure:^(
      NSError *error) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [
      TPDemoProgressUtils showError:error.localizedDescription];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }];
     
    
2. 判断是否已经登录
在程序启动后,如果登录过了就不需要重复登录,session的有效期是45天,直接到设备列表页面。如果没有登录过,就先到登录页进行登录,登录成功后再跳转到设备列表页。
  
   - 
    
     
    
    
     
      // 判断是否已经登录
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      if ([TuyaSmartUser sharedInstance].isLogin) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      // 首页
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [self 
      resetRootViewController:[TYDemoTabBarViewController 
      class]];
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
      } else {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      // 登录页
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [[TYDemoRouteManager sharedInstance] 
      openRoute:kTYDemoPopLoginVC 
      withParams:nil];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
3. Session 失效处理
长期未登录或者密码修改后的账号,在访问服务端接口的时候会返回 Session 过期的错误,需要监听 TuyaSmartUserNotificationUserSessionInvalid 通知,跳转至登录页面重新登录。
  
   - 
    
     
    
    
     
      - (
      void)loadNotification {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [[
      NSNotificationCenter defaultCenter] addObserver:
      self selector:
      @selector(sessionInvalid) name:TuyaSmartUserNotificationUserSessionInvalid object:
      nil];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (
      void)sessionInvalid {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      NSLog(
      @"sessionInvalid");
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      //跳转至登录页面
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              MyLoginViewController *vc = [[MyLoginViewController alloc] init];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      self.window.rootViewController = vc;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
            [
      self.window makeKeyAndVisible];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
(四) 创建家庭
用户登录成功后需要通过 TuyaSmartHomeManager 去获取整个家庭列表的信息,然后初始化其中的一个家庭TuyaSmartHome,获取家庭详情信息,就可以对家庭中的设备进行操作控制。

1. 家庭列表获取
在设备列表页面,我们先获取用户下的家庭列表,如果没有家庭,我们创建一个默认家庭。因为设备激活的时候,需要把设备添加到家庭里面。
获取到家庭列表之后,我们就可以初始化一个家庭,然后从云端获取家庭的详情,刷新首页的设备列表。
  
   - 
    
     
    
    
     
      - (
      void)initData {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
         
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          _homeManager = [[TuyaSmartHomeManager alloc] init];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          _homeManager.delegate = 
      self;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
         
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      // 获取本地的当前家庭
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      NSString *homeId = [[
      NSUserDefaults standardUserDefaults] objectForKey:kDefaultCurrentHomeId];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      if ([homeId longLongValue] > 
      0) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      self.home = [TuyaSmartHome homeWithHomeId:[homeId longLongValue]];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      if (
      self.home) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
                  
      self.home.delegate = 
      self;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
                  
      self.topBarView.leftItem.title = [
      NSString stringWithFormat:
      @"%@ ∨", 
      self.home.homeModel.name];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
                  [TYDemoSmartHomeManager sharedInstance].currentHomeModel = 
      self.home.homeModel;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
                  
      // 刷新设备列表数据
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
                  [
      self reloadDataFromCloud];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              } 
      else {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
                  
      // 如果没有,获取第一个家庭
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
                  [
      self loadFirstHomeData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          } 
      else {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      // 如果没有,获取第一个家庭
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              [
      self loadFirstHomeData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (
      void)reloadDataFromCloud {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          WEAKSELF_AT
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [
      self.refreshControl beginRefreshing];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      // 获取当前家庭的详情,并刷新列表
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [
      self.home getHomeDetailWithSuccess:^(TuyaSmartHomeModel *homeModel) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
             
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              [weakSelf_AT reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          } failure:^(
      NSError *error) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      if ([error.localizedFailureReason isEqualToString:
      @"PERMISSION_DENIED"]) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
                  [weakSelf_AT loadFirstHomeData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              [weakSelf_AT.refreshControl endRefreshing];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          }];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
2. 新增一个家庭
  
   - 
    
     
    
    
     
      // add home
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (
      void)rightBtnAction {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          NSString *homeName = [NSString 
      stringWithFormat:@
      "Home_%@", @(self.homeManager.homes.count)];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          WEAKSELF_AT
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [self.homeManager 
      addHomeWithName:homeName 
      geoName:@
      "hangzhou" 
      rooms:@[@
      "room1"] 
      latitude:
      0 
      longitude:
      0 
      success:^(
      long 
      long homeId) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              [TPDemoProgressUtils 
      showSuccess:@
      "Add Success" 
      toView:nil];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      // 切换到新增家庭
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              TuyaSmartHome *home = [TuyaSmartHome 
      homeWithHomeId:homeId];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              [weakSelf_AT 
      swithCurrentHomeIdWithHomeModel:home.homeModel];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          } 
      failure:^(NSError *error) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              [TPDemoProgressUtils 
      showError:error.localizedDescription];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          }];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
3. 家庭列表信息变化回调
实现 TuyaSmartHomeManagerDelegate 代理协议后,可以在家庭列表更变的回调中进行处理。
  
   - 
    
     
    
    
     
      #pragma 
      mark 
      - 
      TuyaSmartHomeManagerDelegate
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 添加一个家庭
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      homeManager
      :(TuyaSmartHomeManager *)
      manager 
      didAddHome
      :(TuyaSmartHomeModel *)
      home {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      NSLog(@
      "Add a home %@", home.name);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 删除一个家庭
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      homeManager
      :(TuyaSmartHomeManager *)
      manager 
      didRemoveHome
      :(long 
      long)
      homeId {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      // 如果删除的家庭是当前家庭,当前家庭切换到另外一个
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      if ([TYDemoSmartHomeManager sharedInstance].currentHomeModel.homeId == homeId) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      [self loadFirstHomeData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // MQTT连接成功
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      serviceConnectedSuccess {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      // 去云端获取当前家庭的详情,然后去刷新 UI
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self reloadDataFromCloud];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
4. 单个家庭信息变化的回调
实现 TuyaSmartHomeDelegate 代理协议后,可以在单个家庭信息更变的回调中进行处理。
  
   - 
    
     
    
    
     
      #pragma 
      mark 
      - 
      TuyaSmartHomeDelegate
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 家庭的信息更新,例如name
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      homeDidUpdateInfo
      :(TuyaSmartHome *)
      home {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 添加一个房间
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      home
      :(TuyaSmartHome *)
      home 
      didAddRoom
      :(TuyaSmartRoomModel *)
      room {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 删除一个房间
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      home
      :(TuyaSmartHome *)
      home 
      didRemoveRoom
      :(long 
      long)
      roomId {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 我收到的共享设备列表变化
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      homeDidUpdateSharedInfo
      :(TuyaSmartHome *)
      home {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 房间信息变更,例如name
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      home
      :(TuyaSmartHome *)
      home 
      roomInfoUpdate
      :(TuyaSmartRoomModel *)
      room {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 房间与设备,群组的关系变化
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      home
      :(TuyaSmartHome *)
      home 
      roomRelationUpdate
      :(TuyaSmartRoomModel *)
      room {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 添加设备
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      home
      :(TuyaSmartHome *)
      home 
      didAddDeivice
      :(TuyaSmartDeviceModel *)
      device {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 删除设备
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      home
      :(TuyaSmartHome *)
      home 
      didRemoveDeivice
      :(NSString *)
      devId {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 设备信息更新,例如name
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      home
      :(TuyaSmartHome *)
      home 
      deviceInfoUpdate
      :(TuyaSmartDeviceModel *)
      device {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 设备dp数据更新
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      home
      :(TuyaSmartHome *)
      home 
      device
      :(TuyaSmartDeviceModel *)
      device 
      dpsUpdate
      :(NSDictionary *)
      dps {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 添加群组
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      home
      :(TuyaSmartHome *)
      home 
      didAddGroup
      :(TuyaSmartGroupModel *)
      group {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 群组dp数据更新
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      home
      :(TuyaSmartHome *)
      home 
      group
      :(TuyaSmartGroupModel *)
      group 
      dpsUpdate
      :(NSDictionary *)
      dps {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 删除群组
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      home
      :(TuyaSmartHome *)
      home 
      didRemoveGroup
      :(NSString *)
      groupId {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 群组信息更新,例如name
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (void)
      home
      :(TuyaSmartHome *)
      home 
      groupInfoUpdate
      :(TuyaSmartGroupModel *)
      group {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      [self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
(五) 设备配网
设备配网是指设备在云端进行激活注册。
1. 相关类

2. EZ 配网
这里主要介绍下 EZ 模式开发,又称快连模式(SmartConfig)。

  
   - 
    
     
    
    
     
      - (
      void)addDeviceWithEZMode {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
         
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      // 获取token
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          WEAKSELF_AT
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      id<TYDemoDeviceListModuleProtocol> impl = [[TYDemoConfiguration sharedInstance] serviceOfProtocol:
      @protocol(TYDemoDeviceListModuleProtocol)];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      long 
      long homeId = [impl currentHomeId];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [[TuyaSmartActivator sharedInstance] getTokenWithHomeId:homeId success:^(
      NSString *token) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      // 开始配网
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              [weakSelf_AT commitEZModeActionWithToken:token];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          } failure:^(
      NSError *error) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
             
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              info = [
      NSString stringWithFormat:
      @"%@: token fetch failed, error message is %@",
      NSStringFromSelector(_cmd),error.localizedDescription];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              [weakSelf_AT appendConsoleLog:info];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          }];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // 开始配网
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (
      void)commitEZModeActionWithToken:(
      NSString *)token {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [TuyaSmartActivator sharedInstance].delegate = 
      self;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [[TuyaSmartActivator sharedInstance] startConfigWiFi:TYActivatorModeEZ ssid:
      self.ssidField.text password:
      self.passwordField.text token:token timeout:timeout];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      #pragma mark - TuyaSmartActivatorDelegate
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (
      void)activator:(TuyaSmartActivator *)activator didReceiveDevice:(TuyaSmartDeviceModel *)deviceModel error:(
      NSError *)error {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
         
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [
      NSObject cancelPreviousPerformRequestsWithTarget:
      self selector:
      @selector(countDown) object:
      nil];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          timeout = timeLeft;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [
      self hideProgressView];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
         
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      NSString *info = [
      NSString stringWithFormat:
      @"%@: Finished!", 
      NSStringFromSelector(_cmd)];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [
      self appendConsoleLog:info];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      if (error) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      // 配网失败
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              info = [
      NSString stringWithFormat:
      @"%@: Error-%@!", 
      NSStringFromSelector(_cmd), error.localizedDescription];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              [
      self appendConsoleLog:info];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          } 
      else {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      // 配网成功
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              info = [
      NSString stringWithFormat:
      @"%@: Success-You've added device %@ successfully!", 
      NSStringFromSelector(_cmd), deviceModel.name];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              [
      self appendConsoleLog:info];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
智能设备配网成功后就有了联网能力,就可以进行远程控制了。
(六)设备控制
设备激活后,就可以进行智能设备的控制,然后监听设备控制变化的回调。
1. 相关类
 在进行设备控制之前,我们先了解下设备功能点的概念。
在进行设备控制之前,我们先了解下设备功能点的概念。
2. 设备功能点
功能点是对产品功能的抽象表示,是具体智能设备功能的抽象,用于描述产品功能及其参数。
• 功能点 ID:功能点的编码。设备与云端的功能数据通过功能点 ID 进行传输。
• 功能点名称:自定义的功能名称。
• 标识名:功能点 Code 值,用于 App 显示功能名称的多语言管理。支持字母、数字和下划线,以字母开头。
• 数据类型:

• 数据传输类型:
|-可下发可上报:指令数据可以发送给设备,设备数据可以传输给云端。
|- 只上报:数据只支持从设备传输给云端。
|- 只下发:数据只支持从云端发送给设备。
TuyaSmartDeviceModel 类的 dps 属性(NSDictionary 类型)定义了当前设备的状态,称作数据点(DP 点)或功能点
dps 字典里的每个 key 对应一个功能点的 dpId,value 对应一个功能点的 dpValue,dpValue 为该功能点的值
产品功能点定义参见涂鸦开发者平台的产品功能,如下图所示:

发送控制指令按照以下格式:
{"<dpId>":"<dpValue>"}
根据后台该产品的功能点定义,如下:
示例代码
  
   - 
    
     
    
    
     
      - (
      void)publishDps {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      // self.device = [TuyaSmartDevice deviceWithDeviceId:@"your_device_id"];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      // self.device.delegate = self;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
         
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      NSDictionary *dps;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      //设置dpId为1的布尔型功能点示例 作用:开关打开
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          dps = @{
      @"1": @(
      YES)};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      //设置dpId为4的字符串型功能点示例 作用:设置RGB颜色为ff5500
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          dps = @{
      @"4": 
      @"ff5500"};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      //设置dpId为5的枚举型功能点示例 作用:设置档位为2档
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          dps = @{
      @"5": 
      @"2"};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      //设置dpId为6的数值型功能点示例 作用:设置温度为20°
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          dps = @{
      @"6": @(
      20)};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      //设置dpId为15的透传型(byte数组)功能点示例 作用:透传红外数据为1122
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          dps = @{
      @"15": 
      @"1122"};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      //多个功能合并发送
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          dps = @{
      @"1": @(
      YES), 
      @"4": @(ff5500)};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [
      self.device publishDps:dps success:^{
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      NSLog(
      @"publishDps success");
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      //下发成功,状态上报通过 deviceDpsUpdate方法 回调
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          } failure:^(
      NSError *error) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      NSLog(
      @"publishDps failure: %@", error);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          }];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
注意事项
• 控制命令的发送需要特别注意数据类型
比如功能点的数据类型是数值型(value),那控制命令发送的应该是 @{@"2": @(25)} 而不是 @{@"2": @"25"}
• 透传类型传输的 byte 数组是字符串格式(16 进制字符串)、字母需小写并且必须是偶数位
比如正确的格式是: @{@"1": @"011f"} 而不是 @{@"1": @"11f"}
功能点更多概念参见快速入门-功能点相关概念
3. 设备初始化和设备变化代理监听
需要通过 TuyaSmartHome 初始化一个 home 实例,然后调用接口 getHomeDetailWithSuccess:failure: 获取家庭的详情,同步过家庭的详情后,初始化设备才能成功。错误的设备 id 可能会导致初始化失败,此时设备的实例返回 nil。
  
   - 
    
     
    
    
     
      - (
      void)publishDps {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      self.device = [TuyaSmartDevice deviceWithDeviceId:
      @"your_device_id"];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          
      self.device.delegate = 
      self;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
       
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [
      self.device publishDps:@{
      @"1" : @{
      YES}} success:^{
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      NSLog(
      @"publishDps success");
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      //下发成功,状态上报通过 deviceDpsUpdate方法 回调
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          } failure:^(
      NSError *error) {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              
      NSLog(
      @"publishDps failure: %@", error);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          }];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      #pragma mark - TuyaSmartDeviceDelegate
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      /// dp数据更新
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (
      void)device:(TuyaSmartDevice *)device dpsUpdate:(
      NSDictionary *)dps {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          [
      self.tableView reloadData];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      /// 设备信息更新
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (
      void)deviceInfoUpdate:(TuyaSmartDevice *)device {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
         
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      /// 设备被移除
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      - (
      void)deviceRemoved:(TuyaSmartDevice *)device {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
         
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
三、总结
我们已经完成了一个 IoT App 对智能硬件设备的激活入网,设备控制等主要环节,通过上述的流程说明,相信你已经可以基于App SDK完成一个智能家居App的开发,感兴趣就去试试吧,有问题可以评论或者私聊!
四、参考
转载:https://blog.csdn.net/weixin_50563088/article/details/110122221
