Matter 设备配网

更新时间:2024-08-22 02:39:40下载pdf

Matter 设备配网支持 Tuya Matter 设备和三方 Matter 设备配网,两者接入的 API 调用一致,但配网表现有不同。Matter 设备配网类型包含自发现、扫描二维码和手动输入编码配网三种方式。

ThingSmartBusinessExtensionKitMatterExtra 组件提供了比 ThingSmartMatterActivator 更多的功能。如果您仍直接在使用 ThingSmartMatterActivator,请参考 此链接

在开始接入 Matter 设备之前,您需要对项目工程进行配置。在涂鸦,Matter 设备被分为 涂鸦 Matter 设备其他第三方 Matter 设备。对于第三方 Matter 设备,您需对 Xcode 工程进行额外的 Extension Target 配置

前提条件

  • 请确保已经完成 SDK 的 快速集成 工作。

  • 若您需要使用 UI 业务包,请确保您集成的智能生活 App SDK 版本和 UI 业务包版本保持一致,以确保配网、控制的稳定。

主工程配置与集成

权限配置

  1. 打开项目设置。

  2. 选中 主工程 Target > Signing & Capabilities,单击 + Capability,如下图所示:

    Matter 设备配网
  3. 添加 Matter Allow Setup Payload 权限,用于处理 Matter 二维码解析。

  4. 添加 App Groups 权限,用于与 Matter Extension Target 共享数据,注意勾选的 App Group Id 需要与 Matter Extension Target 中配置的一致。

  5. 添加 Background Modes 权限,勾选 Uses Bluetooth LE accessories 权限,用于保证蓝牙通讯稳定性

    配置后最终如图所示:

    Matter 设备配网

Info.plist 配置

  1. 打开 Xcode 项目设置。

  2. 选中 主工程 Target > Info > Custom iOS Target Properties,如下图所示:

    Matter 设备配网
    • 蓝牙隐私权限

      添加 NSBluetoothPeripheralUsageDescription 权限,用于蓝牙使用隐私声明。

    • Bonjour 服务权限

      Matter 强依赖局域网通信,因此需要在主工程的 Info.plist 文件中配置 Bonjour 服务,代码如下:

      <key>NSBonjourServices</key>
          <array>
              <string>_meshcop._udp</string>
              <string>_matter._tcp</string>
              <string>_matterc._udp</string>
              <string>_matterd._udp</string>
          </array>
      

使用 CocoaPods 快速集成

  1. CocoaPods 建议更新至最新版本。

  2. Podfile 文件中添加以下内容:

    platform :ios, '9.0'
    
    target 'Your_Project_Name' do
        pod "ThingSmartMatterKit"
    end
    
  3. 在项目根目录下执行 pod update 命令进行集成。

    CocoaPods 的使用请参考 CocoaPods 官方文档

模块初始化

根据 快速集成 章节指引,在初始化 SDK 完成之后,完成 Matter 模块初始化:

// 初始化 SDK
[[TuyaSmartSDK sharedInstance] startWithAppKey:<#your_app_key#> secretKey:<#your_secret_key#>];

// 初始化 Matter 模块
[ThingSmartMatterActivatorConfig setMatterConfigKey:<#YOUR_APP_GROUP_ID#>];

接口说明

+ (void)setMatterConfigKey:(NSString *)configKey;

参数说明

参数 说明
configKey 工程 App Group ID

示例代码

Objective C:

[ThingSmartMatterActivatorConfig setMatterConfigKey:<#YOUR_APP_GROUP_ID#>];

Swift:

ThingSmartMatterActivatorConfig.setMatterKey("YOUR_APP_GROUP_ID")

Extension Target 配置与集成

注意事项

  • 需要使用 14.1 及以上版本 Xcode。
  • 需要使用 16.1 及以上版本 iOS 系统。
  • 新建 Matter Extension Target,使用默认生成的代码文件即可,然后 请跟随本文配置修改代码文件
  • Matter Extension Target 仅支持 Swift 项目。

权限配置

  1. 打开项目设置。
  2. 选中 主工程 Target > Signing & Capabilities,单击 + Capability
  3. 添加 App Groups 权限,用于与 主工程 Target 共享数据,注意勾选的 App Group Id 需要与 主工程 Target 中配置的一致。

使用 CocoaPods 快速集成

  1. CocoaPods 建议更新至最新版本。

  2. Podfile 文件中添加以下内容:

    platform :ios, '9.0'
    
    target 'Your_Matter_Extension_Target_Name' do
        pod "ThingSmartMatterExtensionKit"
    end
    
  3. 在项目根目录下执行 pod update 命令进行集成。

    CocoaPods 的使用请参考 CocoaPods 官方文档

模块初始化

打开 ExtensionTarget 工程中的 RequestHandler.swift 文件,重写 init 方法。

override init()

接口说明

+ (void)setMatterConfigKey:(NSString *)configKey;

参数说明

参数 说明
configKey 工程 App Group ID

示例代码

Swift:

override init() {
  super.init()
  ThingMatterExtensionSupport.shared.setMatterConfigKey(configKey: <#YOUR_APP_GROUP_ID#>)
}

使用 ThingSmartMatterExtensionKit

按文档生成 Matter Extension Target 工程后,会在 Extension 工程中看到RequestHandler.swift 文件,API 方法由系统提供,按如下代码调用 ThingSmartMatterExtensionKit 接口。

  1. ThingSmartMatterExtensionKit 引入库。

    import ThingSmartMatterExtensionKit
    
  2. 按照以下示例代码,在官方自动生成的方法中调用 API。

    RequestHandler.swift 中的回调方法均由系统自动生成,不可更改

        override func validateDeviceCredential(_ deviceCredential: MatterAddDeviceExtensionRequestHandler.DeviceCredential) async throws {
            ThingMatterExtensionSupport.shared.validateDeviceCredential(deviceCredential)
        }
    
        override func selectWi-FiNetwork(from wifiScanResults: [MatterAddDeviceExtensionRequestHandler.Wi-FiScanResult]) async throws -> MatterAddDeviceExtensionRequestHandler.Wi-FiNetworkAssociation {
            // Use this function to select a Wi-Fi network for the device if your ecosystem has special requirements.
            // Or, return `.defaultSystemNetwork` to use the iOS device's current network.
            return ThingMatterExtensionSupport.shared.selectWi-FiNetwork(from: wifiScanResults)
        }
    
        override func selectThreadNetwork(from threadScanResults: [MatterAddDeviceExtensionRequestHandler.ThreadScanResult]) async throws -> MatterAddDeviceExtensionRequestHandler.ThreadNetworkAssociation {
            // Use this function to select a Thread network for the device if your ecosystem has special requirements.
            // Or, return `.defaultSystemNetwork` to use the default Thread network.
            return ThingMatterExtensionSupport.shared.selectThreadNetwork(from: threadScanResults)
        }
    
        override func commissionDevice(in home: MatterAddDeviceRequest.Home?, onboardingPayload: String, commissioningID: UUID) async throws {
            // Use this function to commission the device with your Matter stack.
            ThingMatterExtensionSupport.shared.commissionDevice(in: home, onboardingPayload: onboardingPayload, commissioningID: commissioningID)
        }
    
        override func rooms(in home: MatterAddDeviceRequest.Home?) async -> [MatterAddDeviceRequest.Room] {
            // Use this function to return the rooms your ecosystem manages.
            // If your ecosystem manages multiple homes, ensure you are returning rooms that belong to the provided home.
            return ThingMatterExtensionSupport.shared.rooms(in: home)
        }
    
        override func configureDevice(named name: String, in room: MatterAddDeviceRequest.Room?) async {
            // Use this function to configure the (now) commissioned device with the given name and room.
            ThingMatterExtensionSupport.shared.configureDevice(named: name, in: room)
        }
    

Matter 能力使用配置

由于 Matter 设备的特性,其一切能力都建立在 Matter Fabric 网络之上。在使用 Matter 设备配网和控制管理等功能前,您需要调用相关接口进行 Matter 基础信息配置。该配置操作需要在进行 Matter 相关业务处理前完成。

Fabric 是 Matter 定义的同一安全域下节点(即设备)的集合,在该安全域下节点能够彼此认证建立安全通信。一个 Fabric 共享同一证书机构(Certificate Authority,CA)的根证书(Root of Trust),同时约定一个 Fabric ID。

Fabric 信息准备

Matter 相关的信息与家庭相关联,因此需在 家庭切换完成家庭首次加载完成 时,调用 - loadFabricWithSpaceId 查询该家庭对应的 Fabric 信息。

接口说明

@interface ThingSmartMatterManager : NSObject
+ (instancetype)sharedInstance;
- (void)loadFabricWithSpaceId:(long long)spaceId
                success:(ThingSuccessHandler)success
                      failure:(ThingFailureError)failure;
@end

参数说明

参数 说明
spaceId 当前家庭 HomeID
success 成功回调
failure 失败回调

示例代码

Objective C:

- (void)loadMatterCurrentHomeFabric:(long long)homeId {
    // 在完成切换家庭/首次加载家庭完成后调用
    [[ThingSmartMatterManager sharedInstance] loadFabricWithSpaceId:homeId success:^{
        NSLog(@"load fabric success");
    } failure:^(NSError *error) {
        NSLog(@"load fabric fail");
    }];
}

Swift:

func loadMatterCurrentHomeFabric(homeId: Int64) {
    // 在完成切换家庭/首次加载家庭完成后调用
    ThingSmartMatterManager.sharedInstance().loadFabric(withSpaceId: homeId) {
        print("load fabric success")
    } failure: { error in
        print("load fabric fail")
    }
}

设备信息准备

相较于其他涂鸦设备,有部分 Matter 设备信息需要提前处理,必须在 家庭设备Fabric 信息准备 两者加载完成后,调用 - getDevicesFabricNodesWithdevIds:callback: 处理家庭中的 Matter 设备。

接口说明

@interface ThingSmartMatterShareManager : NSObject
+ (instancetype)sharedInstance;
- (void)getDevicesFabricNodesWithdevIds:(NSArray <NSString *>*)devIds callback:(void(^)(NSArray <ThingSmartMatterDeviceNodeModel *>*result))callback;
@end

参数说明

参数 说明
devIds 设备 ID 列表

示例代码

Objective C:

- (void)loadMatterDeviceInfo {
    // 在 `- loadFabric` 和 家庭设备加载完成 之后调用
    [[ThingSmartMatterShareManager sharedInstance] getDevicesFabricNodesWithdevIds:deviceIdList callback:^(NSArray<ThingSmartMatterDeviceNodeModel *> *result) {
        NSLog(@"load matter device node succes");
    }];
}

Swift:

func loadMatterDeviceInfo(){
  // 在 `- loadFabric` 和 家庭设备加载完成 之后调用
  ThingSmartMatterShareManager.sharedInstance().getDevicesFabricNodesWithdevIds(deviceIdList) { modelList in
      print("load matter device info success")
  }
}
## 配网流程
App业务拓展 SDKMatter 设备云端设备进入配网模式解析设备二维码1解析设备二维码返回设备信息2alt[扫描设备二维码]解析设备码3解析设备码返回设备信息4alt[输入设备码]开启搜索功能,搜索 Matter 设备5搜索设备返回搜索到的设备列表6alt[搜索设备]请求配网 Token7返回配网 Token8开始激活设备9开始激活设备,并连接设备10完成连接11完成连接12根据设备信息激活设备13根据设备信息激活设备14在云端激活设备15激活成功16完成激活17完成激活18alt[激活设备]App业务拓展 SDKMatter 设备云端Matter 设备配网流程

注册配网类型

基座初始化时,需要注册一下配网的类型,Matter 配网对应为 ThingSmartActivatorTypeMatterModel

接口说明

/// Initialize network configuration types
/// @param typeList Network configuration types
- (void)registerWithActivatorList:(NSArray<ThingSmartActivatorTypeModel *>*)typeList;

参数说明

参数 说明
typeList 配网类型列表

查询 Token

使用涂鸦 SDK 获取配网 Token,然后进行配网。Token 的有效期为 10 分钟,且配置成功后就会失效。再次配网时,需要重新查询 Token。

接口说明

- (void)getTokenWithHomeId:(long long)homeId
                   success:(ThingSuccessString)success
                   failure:(ThingFailureError)failure;

参数说明

参数 说明
homeId 设备将要绑定到的家庭的 ID
success 成功回调,返回配网 Token
failure 失败回调,返回失败原因

二维码/手动码解析

二维码和手动码解析接口,若二维码和手动码错误,则不会返回设备模型。

/// Check the matter code is legal or not. Returns nil if it is invalid.
/// @param qrString The matter QRCode string or Manual Code string.
- (ThingSmartActivatorDeviceModel *)parseSetupCode:(NSString *)qrString;

参数说明

参数 说明
qrString 二维码或者手动设备码信息

开始搜索

开始搜索时,需要传入已注册的 typeList

接口说明

/// Start searching
/// @param typeList Network configuration types
- (void)startSearch:(NSArray <ThingSmartActivatorTypeModel *>*)typeList;

参数说明

参数 说明
typeList 配网类型列表

停止搜索

接口说明

/// Stop searching
/// @param typeList Network configuration types
/// @param clearCache Whether to clear the cache
- (void)stopSearch:(NSArray <ThingSmartActivatorTypeModel *>*)typeList clearCache:(BOOL)clearCache;

参数说明

参数 说明
typeList 配网类型列表
clearCache 是否清空当前搜索设备缓存

搜索设备回调

搜到设备之后,会通过搜索回调返回设备信息。如果失败,则会返回对应的失败信息。

接口说明

/// Device search callback
/// @param service Search instance
/// @param type Network configuration type
/// @param device Discovered device
/// @param errorModel Error callback
- (void)activatorService:(id<ThingSmartActivatorSearchProtocol>)service
            activatorType:(ThingSmartActivatorTypeModel *)type
             didFindDevice:(nullable ThingSmartActivatorDeviceModel *)device
                     error:(nullable ThingSmartActivatorErrorModel *)errorModel;

参数说明

参数 说明
service 配网服务。
type 配网类型。
device 发现设备,返回此次配网的设备模型。
errorModel 如果配网失败或者超时,返回此模型,成功时返回 nil

设备激活

接口说明

/// Activate devices with a single network configuration type
/// @param type Network configuration type
/// @param deviceList Devices to be activated
- (void)startActive:(ThingSmartActivatorTypeModel *)type deviceList:(NSArray<ThingSmartActivatorDeviceModel *>*)deviceList;

参数说明

参数 说明
type 配网类型
deviceList 待激活设备列表,目前仅支持单个设备

Matter 配网链路回调

SDK 会根据设备广播包自动选择最合适的配网链路,并回调给业务层进行相应的页面显示。共有三种类型,涂鸦链路、分享配网链路以及 MatterSupport 链路。
如您需要支持 MatterSupport 链路配网,请参考 Matter设备接入准备。只有配置完成后,才可以进行 MatterSupport 配网。

/// Discoveryed Matter Device.
/// @param typeModel device type model
- (void)matterDeviceDiscoveryed:(ThingMatterDeviceDiscoveriedType *)typeModel;

参数说明

参数 说明
typeModel 具体配网链路

设备 PASE 会话建立成功回调

Matter 设备连接后建立完成密码认证会话建立(Password Authenticated Session Establishment,PASE)会话,将触发 PASE 会话成功回调。

/// Matter commission establish complete, model's type will be known.
/// @param deviceModel Device model.
- (void)matterCommissioningSessionEstablishmentComplete:(ThingSmartActivatorDeviceModel *)deviceModel;

参数说明

参数 说明
deviceModel PASE 会话阶段的 Matter 设备模型,可用于部分数据提取

建立完整 CASE 会话并激活设备上云

完成 PASE 会话后,部分关键信息如设备类型等已经可以拿到,如您确认需要激活设备上云,且完成了证书认证会话建立(Certificate Authenticated Session Establishment,CASE)会话的必要参数组装,则需要继续调用该接口完成 CASE 会话建立。

/// @param deviceModel the matter devicemodel.
/// @param typeModel Network configuration type.
- (void)continueCommissionDevice:(ThingSmartActivatorDeviceModel *)deviceModel typeModel:(ThingSmartActivatorTypeMatterModel *)typeModel;

参数说明

参数 说明
deviceModel PASE 会话阶段完成后回调的 Matter 设备模型,从 matterCommissioningSessionEstablishmentComplete 回调中获取。
typeModel 组装的 CASE 会话参数模型,双模设备需要 ssidpassword,thread 设备需要 gwDevId

设备认证回调

如果您配对的是一个未经过官方认证的 Matter 设备,那么会触发认证回调。如果触发了该回调,在您选择继续或放弃前,配网流程将会暂停。

// Matter device attestation fails, use `-continueCommissioningDevice:ignoreAttestationFailure:error:` to continue OR interrupt.
///
/// **Notice**
/// Usually app will display an alert view to the user, allowing the user to judge whether to ignore the attestation failure.
///
/// @param device the failure device.
/// @param error the failure error info.
- (void)matterDeviceAttestation:(void *)device error:(NSError * _Nonnull)error;

参数说明

参数 说明
device 配网链路中的设备对象地址指针
error 未通过认证的错误信息

信任未认证的设备并继续配网

如您认为该设备证书可以被信任,可以调用该接口继续配网。

/// Continue the pairing or NOT.
///
/// **Notice:** Can only be used after the `-matterDeviceAttestation:error:` delegate callback.
///
/// @param device It MUST BE the device object through the `-matterDeviceAttestation:error:` delegate callback.
/// @param ignoreAttestationFailure Ignore the attestation fail or NOT. `YES` - continue pairing, `NO` - interrupt pairing.
/// @param error the error info.
- (void)continueCommissioningDevice:(void *)device
           ignoreAttestationFailure:(BOOL)ignoreAttestationFailure
                              error:(NSError * __autoreleasing *)error;

参数说明

参数 说明
device Attestation 回调方法中的设备对象地址指针,必须透传回调上来的参数,不可进行其他操作
ignoreAttestationFailure 是否忽略未认证信息
error 该操作执行后可能的错误信息

设备激活结果回调

// Device network configuration result callback
/// @param service Device network configuration implementation object
/// @param type Network configuration type
/// @param devices Devices being configured
/// @param errorModel Error encountered during network configuration
- (void)activatorService:(id<ThingSmartActivatorActiveProtocol>)service
           activatorType:(ThingSmartActivatorTypeModel *)type
       didReceiveDevices:(nullable NSArray<ThingSmartActivatorDeviceModel *> *)devices
                   error:(nullable ThingSmartActivatorErrorModel *)errorModel;

参数说明

参数 说明
service 配网服务
type 配网类型
devices 激活成功设备
errorModel 如果配网失败或者超时,返回此模型,成功时返回 nil

停止激活

接口说明

/// Stop activating devices
/// @param typeList Array of network configuration types
/// @param clearCache Whether to clear the cache
- (void)stopActive:(NSArray <ThingSmartActivatorTypeModel *>*)typeList clearCache:(BOOL)clearCache;

参数说明

参数 说明
typeList 配网类型
clearCache 清空缓存设备信息

错误码说明

配网失败或者配网超时的情况下,会返回 ThingSmartActivatorErrorModel

@interface ThingSmartActivatorErrorModel : NSObject
@property (nonatomic, strong) ThingSmartActivatorDeviceModel *deviceModel;
@property (nonatomic) NSError *error;
@end

其中 error 对应的错误码,定义在 ThingSmartActivatorDiscoveryError 中。

示例代码

搜索配网

Swift

class BEMatterTableViewController: UITableViewController {

    private var typeModel: ThingSmartActivatorTypeMatterModel = {
        let type = ThingSmartActivatorTypeMatterModel()
        type.type = ThingSmartActivatorType.matter
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.matter)
        type.timeout = 180
        return type
    }()

    lazy var discovery: ThingSmartActivatorDiscovery = {
        let discovery = ThingSmartActivatorDiscovery()
        discovery.register(withActivatorList: [self.typeModel])
        discovery.setupDelegate(self)
        discovery.loadConfig()
        return discovery
    }()

    func bindMatter(qrcode codeStr: String?) -> Void {
        let homeId = (Home.current?.homeId)!
        let payload = self.discovery.parseSetupCode(codeStr ?? "")
        let activator = ThingSmartActivator()
        activator.getTokenWithHomeId(homeId, success: { [weak self] (token) in
            guard let self = self else { return }
            self.typeModel.token = token ?? ""
            self.typeModel.spaceId = homeId
            self.discovery.startActive(self.typeModel, deviceList:[payload])
            SVProgressHUD.show(withStatus: NSLocalizedString("Configuring", comment: ""))
        }, failure: { (error) in
            let errorMessage = error?.localizedDescription ?? ""
            SVProgressHUD.showError(withStatus: errorMessage)
        })
    }

    private func stopConfigWifi() {
        SVProgressHUD.dismiss()
        discovery.stopActive([typeModel], clearCache: true)
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        discovery.startSearch([self.typeModel])
    }

}

extension BEMatterTableViewController: ThingSmartActivatorSearchDelegate {
    func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didFindDevice device: ThingSmartActivatorDeviceModel?, error errorModel: ThingSmartActivatorErrorModel?) {
        if let device = device {
            if device.deviceModelType == ThingSearchDeviceModelTypeMatterWifi {
                self.typeModel.ssid = ssid.text ?? ""
                self.typeModel.password = password.text ?? ""
                print("Please use Dual Mode to pair: %@", device.uniqueID)

            }

            if device.deviceModelType == ThingSearchDeviceModelTypeMatterThread {
                self.typeModel.gwDevId = "gateway deivce id"
            }
            let homeId = (Home.current?.homeId)!
            let payload = self.discovery.parseSetupCode(codeStr ?? "")
            let activator = ThingSmartActivator()
            activator.getTokenWithHomeId(homeId, success: { [weak self] (token) in
                guard let self = self else { return }
                self.typeModel.token = token ?? ""
                self.typeModel.spaceId = homeId
                self.discovery.startActive(self.typeModel, deviceList:[payload])
                SVProgressHUD.show(withStatus: NSLocalizedString("Configuring", comment: ""))
            }, failure: { (error) in
                let errorMessage = error?.localizedDescription ?? ""
                SVProgressHUD.showError(withStatus: errorMessage)
            })
        }

        if let errorModel = errorModel {
            // Error
            SVProgressHUD.showError(withStatus: errorModel.error.localizedDescription)
        }
    }
}

extension BEMatterTableViewController: ThingSmartActivatorActiveDelegate {
    func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
        if errorModel != nil {
            SVProgressHUD.showError(withStatus: "Bind Failure. (\(errorModel?.error.localizedDescription ?? ""))")
            return
        }

        let device = devices?.first
        isSuccess = true
        SVProgressHUD.show(withStatus: "Bind Success. \n devId: \(device?.uniqueID ?? "") \n name: \(device?.name ?? "")")
    }
}

extension BEMatterTableViewController: ThingSmartActivatorDeviceExpandDelegate {
    func matterDeviceDiscoveryed(_ typeModel: ThingMatterDeviceDiscoveriedType) {
        deviceTypeModel = typeModel
    }

    func matterCommissioningSessionEstablishmentComplete(_ deviceModel: ThingSmartActivatorDeviceModel) {
        if deviceTypeModel?.deviceType == .wifi {
            self.typeModel.ssid = ssid.text ?? ""
            self.typeModel.password = password.text ?? ""
            self.discovery.continueCommissionDevice(deviceModel, typeModel: self.typeModel)
        }

        ///
        if deviceTypeModel?.deviceType == .thread {
            self.typeModel.gwDevId = "your gateway id"
            self.discovery.continueCommissionDevice(deviceModel, typeModel: self.typeModel)
        }

    }

    func matterDeviceAttestation(_ device: UnsafeMutableRawPointer, error: Error) {
        let alertControl = UIAlertController(title: "Attestation", message: "Should Continue?", preferredStyle: .alert)
        let alertAction = UIAlertAction(title: "Continue", style: .default) { _ in
            self.discovery.continueCommissioningDevice(device, ignoreAttestationFailure: true, error: nil)
        }
        let canAction = UIAlertAction(title: "Cancel", style: .cancel) { _ in
            self.discovery.continueCommissioningDevice(device, ignoreAttestationFailure: false, error: nil)
        }

        alertControl.addAction(alertAction)
        alertControl.addAction(canAction)

        self.present(alertControl, animated: true)
    }

}

Objective-C


- (void)getToken {
    ThingSmartActivator *wiredActivator = [[ThingSmartActivator alloc] init];
    [wiredActivator getTokenWithHomeId:homeId success:^(NSString *token) {
        NSLog(@"getToken success: %@", token);
        [self startConfigWiFi:token];
    } failure:^(NSError *error) {
        NSLog(@"getToken failure: %@", error.localizedDescription);
    }];
}

- (void)startConfigWiFi:(NSString *)token {
  ThingSmartActivatorTypeMatterModel *matterType  = [[ThingSmartActivatorTypeMatterModel alloc] init];
  matterType.type = ThingSmartActivatorTypeMatter;
  matterType.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeMatter);
  matterType.timeout = 120;
  matterType.spaceId = homeId;
  matterType.token = token;

  [self.discovery registerWithActivatorList:@[matterType]];
  [self.discovery setupDelegate:self];
  [self.discovery startSearch:@[matterType]];
}

- (void)activatorService:(id<ThingSmartActivatorSearchProtocol>)service activatorType:(ThingSmartActivatorTypeModel *)type didFindDevice:(ThingSmartActivatorDeviceModel *)device error:(ThingSmartActivatorErrorModel *)errorModel {

    if (errorModel) {
        [self _connectWifiError:errorModel];
        return;
    }

    if (device) {
        [self _handleDevice:device];
    }
}

- (void)_handleDevice:(ThingSmartActivatorDeviceModel *)deviceModel {
     ThingSmartActivatorTypeMatterModel *matterType = (ThingSmartActivatorTypeMatterModel *)[self.discovery activatorTypeModelWith:ThingSmartActivatorTypeMatter];
    [self.discovery startActive:matterType deviceList:@[deviceModel]];
}


- (void)matterRoutingComplete:(ThingSmartMatterRoutingType)routingType {
    self.routingType = routingType;
    if (routingType == ThingSmartMatterRoutingTypeSupport) {

    }
}

-(void)matterCommissioningSessionEstablishmentComplete:(ThingSmartActivatorDeviceModel *)deviceModel {


    if (self.routingType == ThingSmartMatterRoutingTypeThing && deviceModel.deviceModelType == ThingSearchDeviceModelTypeMatterThread) {
        self.matterType..gwDevId = gatewayID;
        [self.discovery continueCommissionDevice:deviceModel typeModel:self.matterType];
    }

    if (self.routingType == ThingSmartMatterRoutingTypeThing && deviceModel.deviceModelType == ThingSearchDeviceModelTypeMatterWifi) {

        self.matterType.ssid = factoryConfig.ssid;
        self.matterType.password = factoryConfig.password;
        [self.discovery continueCommissionDevice:deviceModel typeModel:self.matterType];

    }

}

- (void)activatorService:(id<ThingSmartActivatorActiveProtocol>)service
           activatorType:(ThingSmartActivatorTypeModel *)type
       didReceiveDevices:(nullable NSArray<ThingSmartActivatorDeviceModel *> *)devices
                   error:(nullable ThingSmartActivatorErrorModel *)errorModel {
     if (devices && devices.count > 0) {

     }
}

- (ThingSmartActivatorDiscovery *)discovery {
    if (!_discovery) {
        _discovery = [[ThingSmartActivatorDiscovery alloc] init];
    }
    return _discovery;
}

二维码/手动输入码配网

Swift

class BEMatterTableViewController: UITableViewController {
   /// UI 部分

    private var typeModel: ThingSmartActivatorTypeMatterModel = {
        let type = ThingSmartActivatorTypeMatterModel()
        type.type = ThingSmartActivatorType.matter
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.matter)
        type.timeout = 180
        return type
    }()

    lazy var discovery: ThingSmartActivatorDiscovery = {
        let discovery = ThingSmartActivatorDiscovery()
        discovery.register(withActivatorList: [self.typeModel])
        discovery.setupDelegate(self)
        discovery.loadConfig()
        return discovery
    }()

    func bindMatter(qrcode codeStr: String?) -> Void {
        let homeId = (Home.current?.homeId)!
        let payload = self.discovery.parseSetupCode(codeStr ?? "")
        let activator = ThingSmartActivator()
        activator.getTokenWithHomeId(homeId, success: { [weak self] (token) in
            guard let self = self else { return }
            self.typeModel.token = token ?? ""
            self.typeModel.spaceId = homeId
            self.discovery.startActive(self.typeModel, deviceList:[payload])
            SVProgressHUD.show(withStatus: NSLocalizedString("Configuring", comment: ""))
        }, failure: { (error) in
            let errorMessage = error?.localizedDescription ?? ""
            SVProgressHUD.showError(withStatus: errorMessage)
        })
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let vc = QRCodeScanerViewController()
        vc.scanCallback = { [weak self] codeStr in
            self?.bindMatter(qrcode: codeStr)
        }
        navigationController?.pushViewController(vc, animated: true)
    }

}

extension BEMatterTableViewController: ThingSmartActivatorActiveDelegate {
    func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
        if errorModel != nil {
            SVProgressHUD.showError(withStatus: "Bind Failure. (\(errorModel?.error.localizedDescription ?? ""))")
            return
        }

        let device = devices?.first
        isSuccess = true
        SVProgressHUD.show(withStatus: "Bind Success. \n devId: \(device?.uniqueID ?? "") \n name: \(device?.name ?? "")")
    }
}

extension BEMatterTableViewController: ThingSmartActivatorDeviceExpandDelegate {
    func matterDeviceDiscoveryed(_ typeModel: ThingMatterDeviceDiscoveriedType) {
        deviceTypeModel = typeModel
    }

    func matterCommissioningSessionEstablishmentComplete(_ deviceModel: ThingSmartActivatorDeviceModel) {
        if deviceTypeModel?.deviceType == .wifi {
            self.typeModel.ssid = ssid.text ?? ""
            self.typeModel.password = password.text ?? ""
            self.discovery.continueCommissionDevice(deviceModel, typeModel: self.typeModel)
        }

        ///
        if deviceTypeModel?.deviceType == .thread {
            self.typeModel.gwDevId = "your gateway id"
            self.discovery.continueCommissionDevice(deviceModel, typeModel: self.typeModel)
        }

    }

    func matterDeviceAttestation(_ device: UnsafeMutableRawPointer, error: Error) {
        let alertControl = UIAlertController(title: "Attestation", message: "Should Continue?", preferredStyle: .alert)
        let alertAction = UIAlertAction(title: "Continue", style: .default) { _ in
            self.discovery.continueCommissioningDevice(device, ignoreAttestationFailure: true, error: nil)
        }
        let canAction = UIAlertAction(title: "Cancel", style: .cancel) { _ in
            self.discovery.continueCommissioningDevice(device, ignoreAttestationFailure: false, error: nil)
        }

        alertControl.addAction(alertAction)
        alertControl.addAction(canAction)

        self.present(alertControl, animated: true)
    }

}

Objective-C


- (void)getToken {
    ThingSmartActivator *wiredActivator = [[ThingSmartActivator alloc] init];
    [wiredActivator getTokenWithHomeId:homeId success:^(NSString *token) {
        NSLog(@"getToken success: %@", token);
        [self startConfigWiFi:token];
    } failure:^(NSError *error) {
        NSLog(@"getToken failure: %@", error.localizedDescription);
    }];
}

- (void)startConfigWiFi:(NSString *)token {
  ThingSmartActivatorTypeMatterModel *matterType  = [[ThingSmartActivatorTypeMatterModel alloc] init];
  matterType.type = ThingSmartActivatorTypeMatter;
  matterType.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeMatter);
  matterType.timeout = 120;
  matterType.spaceId = homeId;
  matterType.token = token;

  [self.discovery registerWithActivatorList:@[matterType]];
  [self.discovery setupDelegate:self];

  ThingSmartActivatorDeviceModel *deviceModel = [self.discovery parseSetupCode:code];
  if (deviceModel) {
    [self.discovery startActive:matterType deviceList:@[deviceModel]];
  } else {

  }
}
//Follow-up processing logic is consistent with search activate