Last Updated on : 2024-08-19 07:42:55download
This topic describes the device pairing service, including Bluetooth devices, wired devices, Zigbee devices, and Matter devices.
Bluetooth devices encompass Bluetooth Low Energy (LE), Bluetooth mesh, Bluetooth combo devices, and beacon devices. They can be discovered through a Bluetooth scan and then paired. This section describes how to use the BizBundle SDK to implement hybrid Bluetooth pairing.
Add the following declarations in info.plist
.
Turn on Bluetooth on the mobile phone and grant the app permission to access Bluetooth. If the app does not have Bluetooth permissions, prompt the user to grant access.
Search for different types of Bluetooth devices simultaneously.
class BleScanModeTableViewController: UIViewController {
var deviceList:[ThingSmartActivatorDeviceModel] = []
private var bleModel: ThingSmartActivatorTypeBleModel = {
let type = ThingSmartActivatorTypeBleModel()
type.type = ThingSmartActivatorType.ble
type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.ble)
type.timeout = 120
if let currentHome = Home.current {
type.spaceId = currentHome.homeId
} else {
assert((Home.current != nil),"Home cannot be nil, need to create a Home")
}
return type
}()
private var sigModel: ThingSmartActivatorTypeSigMeshModel = {
let type = ThingSmartActivatorTypeSigMeshModel()
type.type = ThingSmartActivatorType.sigMesh
type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.sigMesh)
type.timeout = 120
if let currentHome = Home.current {
type.spaceId = currentHome.homeId
} else {
assert((Home.current != nil),"Home cannot be nil, need to create a Home")
}
return type
}()
private var beaconModel: ThingSmartActivatorTypeBeaconModel = {
let type = ThingSmartActivatorTypeBeaconModel()
type.type = ThingSmartActivatorType.beacon
type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.beacon)
type.timeout = 120
return type
}()
lazy var discovery: ThingSmartActivatorDiscovery = {
let discovery = ThingSmartActivatorDiscovery()
discovery.register(withActivatorList: [self.bleModel,self.sigModel,self.beaconModel])
discovery.setupDelegate(self)
discovery.loadConfig()
if let currentHome = Home.current {
discovery.currentSpaceId(currentHome.homeId)
} else {
assert((Home.current != nil),"Home cannot be nil, need to create a Home")
}
return discovery
}()
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
stopConfiguring()
}
@IBAction func searchTapped(_ sender: UIBarButtonItem) {
discovery.startSearch([self.bleModel,self.sigModel,self.beaconModel])
SVProgressHUD.show(withStatus: NSLocalizedString("Searching", comment: ""))
}
// MARK: - Private method
private func stopConfiguring() {
discovery.stopSearch([self.bleModel,self.sigModel,self.beaconModel], clearCache: true)
discovery.stopActive([self.bleModel,self.sigModel,self.beaconModel], clearCache: true)
discovery.removeDelegate(self)
}
}
// MARK: - ThingSmartActivatorSearchDelegate
extension BleScanModeTableViewController: ThingSmartActivatorSearchDelegate {
func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didFindDevice device: ThingSmartActivatorDeviceModel?, error errorModel: ThingSmartActivatorErrorModel?) {
if var device = device {
deviceList.append(device)
// display devices
}
}
}
The required pairing parameters may vary depending on the type of Bluetooth devices.
Device type | Pairing information |
---|---|
ThingSearchDeviceModelTypeBle | Pair a single device, no additional parameters required. |
ThingSearchDeviceModelTypeSigMeshSubDevice | Pair multiple devices in one go, no additional parameters required. |
ThingSearchDeviceModelTypeBeacon | Pair multiple devices in one go, no additional parameters required. |
ThingSearchDeviceModelTypeBleWifi | Pair a single device, with Wi-Fi name and password required. |
private func startConfiguration(_ deviceModel: ThingSmartActivatorDeviceModel) {
if deviceModel.deviceModelType == ThingSearchDeviceModelTypeBle {
discovery.startActive(self.bleModel, deviceList: [deviceModel])
} else if deviceModel.deviceModelType == ThingSearchDeviceModelTypeBleWifi {
self.bleModel.ssid = "name of the router"
self.bleModel.password = "password of the router"
discovery.startActive(self.bleModel, deviceList: [deviceModel])
} else if deviceModel.deviceModelType == ThingSearchDeviceModelTypeSigMeshSubDevice {
var sigMeshList:[ThingSmartActivatorDeviceModel] = []
for device in deviceList {
if device.deviceModelType == ThingSearchDeviceModelTypeSigMeshSubDevice {
sigMeshList.append(device)
}
}
discovery.startActive(self.sigModel, deviceList: sigMeshList)
} else if deviceModel.deviceModelType == ThingSearchDeviceModelTypeBeacon {
var beaconList:[ThingSmartActivatorDeviceModel] = []
for device in deviceList {
if device.deviceModelType == ThingSearchDeviceModelTypeBeacon {
beaconList.append(device)
}
}
discovery.startActive(self.beaconModel, deviceList: beaconList)
}
}
When pairing devices of different types, compare the returned device information with the selected devices, especially when pairing multiple devices simultaneously.
extension BleScanModeTableViewController: ThingSmartActivatorActiveDelegate {
func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
if errorModel != nil {
var failureDevice: ThingSmartActivatorDeviceModel?
if errorModel?.deviceModel != nil {
self.deviceList.forEach { obj in
if ((errorModel?.deviceModel!.isEqual(toDevice: obj)) != nil) {
failureDevice = obj
}
}
}
SVProgressHUD.showError(withStatus: NSLocalizedString("Failed to Activate Device \(String(describing: failureDevice?.name))", comment: ""))
return
}
if let devices = devices {
let device = devices.first
var successDevice: ThingSmartActivatorDeviceModel?
self.deviceList.forEach { obj in
if device!.isEqual(toDevice: obj) {
successDevice = obj
}
}
successDevice?.deviceStatus = ThingSearchDeviceStatusNetwork
}
}
}
The mobile phone and the wired gateway are connected to the same router.
The app has been granted permission to access the local network.
Case 1: Scan for devices along with other scan capabilities.
Your app scans for multiple types of devices at the same time, such as Bluetooth and wired gateways. In this case, the Bluetooth device calls the scan method in the Bluetooth SDK, while the wired gateway calls the scan method in other SDKs, leading to inconsistent result models. Identifying composite-protocol devices is complex, as they can be discovered and paired using various scan methods.
To simplify the pairing process, you can use the composite scan capability, which abstracts the differences of various protocols with a unified method and model.
class CompositeScanModeTableViewController: UIViewController {
var deviceList:[ThingSmartActivatorDeviceModel] = []
private var wiredModel: ThingSmartActivatorTypeWiredModel = {
let type = ThingSmartActivatorTypeWiredModel()
type.type = .wired
type.typeName = NSStringFromThingSmartActivatorType(.wired)
type.timeout = 120
if let currentHome = Home.current {
type.spaceId = currentHome.homeId
} else {
assert((Home.current != nil),"Home cannot be nil, need to create a Home")
}
return type
}()
private var bleModel: ThingSmartActivatorTypeBleModel = {
let type = ThingSmartActivatorTypeBleModel()
type.type = ThingSmartActivatorType.ble
type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.ble)
type.timeout = 120
if let currentHome = Home.current {
type.spaceId = currentHome.homeId
} else {
assert((Home.current != nil),"Home cannot be nil, need to create a Home")
}
return type
}()
private var sigModel: ThingSmartActivatorTypeSigMeshModel = {
let type = ThingSmartActivatorTypeSigMeshModel()
type.type = ThingSmartActivatorType.sigMesh
type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.sigMesh)
type.timeout = 120
if let currentHome = Home.current {
type.spaceId = currentHome.homeId
} else {
assert((Home.current != nil),"Home cannot be nil, need to create a Home")
}
return type
}()
private var beaconModel: ThingSmartActivatorTypeBeaconModel = {
let type = ThingSmartActivatorTypeBeaconModel()
type.type = ThingSmartActivatorType.beacon
type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.beacon)
type.timeout = 120
return type
}()
lazy var discovery: ThingSmartActivatorDiscovery = {
let discovery = ThingSmartActivatorDiscovery()
discovery.register(withActivatorList: [self.bleModel,self.sigModel,self.beaconModel])
discovery.setupDelegate(self)
discovery.loadConfig()
if let currentHome = Home.current {
discovery.currentSpaceId(currentHome.homeId)
} else {
assert((Home.current != nil),"Home cannot be nil, need to create a Home")
}
return discovery
}()
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
stopConfiguring()
}
@IBAction func searchTapped(_ sender: UIBarButtonItem) {
discovery.startSearch([self.wiredModel,self.bleModel,self.sigModel,self.beaconModel])
SVProgressHUD.show(withStatus: NSLocalizedString("Searching", comment: ""))
}
// MARK: - Private method
private func stopConfiguring() {
discovery.stopSearch([self.wiredModel,self.bleModel,self.sigModel,self.beaconModel], clearCache: true)
discovery.stopActive([self.wiredModel,self.bleModel,self.sigModel,self.beaconModel], clearCache: true)
discovery.removeDelegate(self)
}
private func startConfiguration(_ deviceModel: ThingSmartActivatorDeviceModel) {
// Omit features
}
}
// MARK: - ThingSmartActivatorSearchDelegate
extension CompositeScanModeTableViewController: ThingSmartActivatorSearchDelegate {
func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didFindDevice device: ThingSmartActivatorDeviceModel?, error errorModel: ThingSmartActivatorErrorModel?) {
if var device = device {
deviceList.append(device)
// display devices
}
}
}
Composite scan enables the discovered Bluetooth device and wired gateway to be returned with the same callback and unified data entity, eliminating the need for data unity and unique identifiers. Then, the discovered device can be paired using the corresponding pairing capability.
Case 2: Independent scanning
class BEZigbeeGatewayViewController: UIViewController {
// MARK: - Property
private var token: String = ""
private var isSuccess = false
@IBOutlet weak var tableview: UITableView!
var deviceList:[ThingSmartActivatorDeviceModel] = []
private var typeModel: ThingSmartActivatorTypeWiredModel = {
let type = ThingSmartActivatorTypeWiredModel()
type.type = ThingSmartActivatorType.wired
type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.wired)
type.timeout = 120
if let currentHome = Home.current {
type.spaceId = currentHome.homeId
} else {
assert((Home.current != nil),"Home cannot be nil, need to create a Home")
}
return type
}()
lazy var discovery: ThingSmartActivatorDiscovery = {
let discovery = ThingSmartActivatorDiscovery()
discovery.register(withActivatorList: [self.typeModel])
discovery.setupDelegate(self)
discovery.loadConfig()
return discovery
}()
// MARK: - Lifecycle
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
stopConfigWifi()
}
// MARK: - IBAction
@IBAction func searchTapped(_ sender: UIBarButtonItem) {
discovery.startSearch([self.typeModel])
SVProgressHUD.show(withStatus: NSLocalizedString("Searching", comment: ""))
}
private func stopConfigWifi() {
if !isSuccess {
SVProgressHUD.dismiss()
}
discovery.stopActive([self.typeModel], clearCache: true)
discovery.removeDelegate(self)
}
}
extension BEZigbeeGatewayViewController: ThingSmartActivatorSearchDelegate {
func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didFindDevice device: ThingSmartActivatorDeviceModel?, error errorModel: ThingSmartActivatorErrorModel?) {
if (device != nil) {
SVProgressHUD.dismiss()
deviceList.append(device!)
tableview.reloadData()
}
}
func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didUpdateDevice device: ThingSmartActivatorDeviceModel) {
}
}
During device pairing, you can identify the device type with the parameters of the device model deviceModelType
.
class CompositeScanModeTableViewController: UIViewController {
// Omit other features
private func startConfiguration(_ deviceModel: ThingSmartActivatorDeviceModel) {
if deviceModel.deviceModelType == ThingSearchDeviceModelTypeBle {
discovery.startActive(self.bleModel, deviceList: [deviceModel])
} else if deviceModel.deviceModelType == ThingSearchDeviceModelTypeBleWifi {
self.bleModel.ssid = "name of the router"
self.bleModel.password = "password of the router"
discovery.startActive(self.bleModel, deviceList: [deviceModel])
} else if deviceModel.deviceModelType == ThingSearchDeviceModelTypeSigMeshSubDevice {
var sigMeshList:[ThingSmartActivatorDeviceModel] = []
for device in deviceList {
if device.deviceModelType == ThingSearchDeviceModelTypeSigMeshSubDevice {
sigMeshList.append(device)
}
}
discovery.startActive(self.sigModel, deviceList: sigMeshList)
} else if deviceModel.deviceModelType == ThingSearchDeviceModelTypeBeacon {
var beaconList:[ThingSmartActivatorDeviceModel] = []
for device in deviceList {
if device.deviceModelType == ThingSearchDeviceModelTypeBeacon {
beaconList.append(device)
}
}
discovery.startActive(self.beaconModel, deviceList: beaconList)
} else if deviceModel.deviceModelType == ThingSearchDeviceModelTypeWired {
guard let homeID = Home.current?.homeId else { return }
SVProgressHUD.show(withStatus: NSLocalizedString("Requesting for Token", comment: ""))
ThingSmartActivator.sharedInstance()?.getTokenWithHomeId(homeID, success: { [weak self] (token) in
guard let self = self else { return }
self.wiredModel.token = "token"
discovery.startActive(self.wiredModel, deviceList: [deviceModel])
}, failure: { (error) in
let errorMessage = error?.localizedDescription ?? ""
SVProgressHUD.showError(withStatus: errorMessage)
})
}
}
}
extension CompositeScanModeTableViewController: ThingSmartActivatorActiveDelegate {
func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
if errorModel != nil {
var failureDevice: ThingSmartActivatorDeviceModel?
if errorModel?.deviceModel != nil {
self.deviceList.forEach { obj in
if ((errorModel?.deviceModel!.isEqual(toDevice: obj)) != nil) {
failureDevice = obj
}
}
}
SVProgressHUD.showError(withStatus: NSLocalizedString("Failed to Activate Device \(String(describing: failureDevice?.name))", comment: ""))
return
}
if let devices = devices {
let device = devices.first
var successDevice: ThingSmartActivatorDeviceModel?
self.deviceList.forEach { obj in
if device!.isEqual(toDevice: obj) {
successDevice = obj
}
}
successDevice?.deviceStatus = ThingSearchDeviceStatusNetwork
}
}
}
A Zigbee device relies on a Zigbee gateway to connect to the cloud. Therefore, the pairing process requires a specific gateway that processes device activation and notifications. The target gateway must be online.
Filter the devices in the current home.
Find suitable Zigbee gateways and make sure they are online.
Select the preferred gateway.
If there is no suitable gateway, prompt the user to add one.
var gatewayList: [ThingSmartDeviceModel] = []
private func getGatewayList() {
if Home.current != nil {
home = ThingSmartHome(homeId: Home.current!.homeId)
guard let list = home?.deviceList else { return }
gatewayList = list.filter { $0.deviceType == ThingSmartDeviceModelTypeZigbeeGateway && $0.isOnline == true}
}
}
The discovery of the Zigbee device indicates successful pairing.
class BEZigbeeSubdeviceTableViewController: UITableViewController {
// MARK: - IBOutlet
@IBOutlet weak var gatewayNameLabel: UILabel!
// MARK: - Property
var gateway: ThingSmartDeviceModel?
private var isSuccess = false
var deviceList:[ThingSmartActivatorDeviceModel] = []
private var typeModel: ThingSmartActivatorTypeSubDeviceModel = {
let type = ThingSmartActivatorTypeSubDeviceModel()
type.type = ThingSmartActivatorType.subDevice
type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.subDevice)
type.timeout = 120
return type
}()
lazy var discovery: ThingSmartActivatorDiscovery = {
let discovery = ThingSmartActivatorDiscovery()
discovery.register(withActivatorList: [self.typeModel])
discovery.setupDelegate(self)
discovery.loadConfig()
return discovery
}()
// MARK: - Lifecycle
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
gatewayNameLabel.text = gateway?.name
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
stopConfiguring()
}
override func viewDidLoad() {
}
private func stopConfiguring() {
guard let deviceID = gateway?.devId else { return }
if !isSuccess {
SVProgressHUD.dismiss()
}
discovery.stopSearch([typeModel], clearCache: true)
discovery.stopActive([typeModel], clearCache: true)
discovery.removeDelegate(self)
}
// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard segue.identifier == "Choose Gateway",
let vc = segue.destination as? BEChooseGatewayTableViewController
else { return }
vc.selectedGateway = gateway
vc.delegate = self
}
// MARK: - IBAction
@IBAction func searchTapped(_ sender: UIBarButtonItem) {
guard let gateway = gateway else {
Alert.showBasicAlert(on: self, with: NSLocalizedString("Select Zigbee Gateway", comment: ""), message: NSLocalizedString("You must have one Zigbee gateway selected.", comment: ""))
return
}
SVProgressHUD.show(withStatus: NSLocalizedString("Configuring", comment: ""))
typeModel.gwDevId = gateway.devId
discovery.startSearch([typeModel])
}
// MARK: - Table view data source
}
extension BEZigbeeSubdeviceTableViewController: ThingSmartActivatorSearchDelegate {
func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didFindDevice device: ThingSmartActivatorDeviceModel?, error errorModel: ThingSmartActivatorErrorModel?) {
if device != nil && errorModel == nil {
// Success
let name = device?.name ?? NSLocalizedString("Unknown Name", comment: "Unknown name device.")
SVProgressHUD.showSuccess(withStatus: NSLocalizedString("Successfully Added \(name)", comment: "Successfully added one device."))
isSuccess = true
SVProgressHUD.dismiss()
}
if let error = errorModel?.error {
// Error
SVProgressHUD.showError(withStatus: error.localizedDescription)
}
}
func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didUpdateDevice device: ThingSmartActivatorDeviceModel) {
}
}
This section describes how to pair a Matter device through searching. For pairing with QR code, see Matter Pairing Implementation in the iOS Home SDK Sample.
Declare the required permissions for your project. See Prepare for Integration with Matter Device.
Turn on Bluetooth on the mobile phone and grant the app permission to access Bluetooth. Connect the mobile phone to a 2.4 GHz Wi-Fi network. For more information about Bluetooth permissions configuration, see Requisites for Bluetooth Pairing.
Create a ThingSmartActivatorTypeMatterModel
object to search for devices. spaceId
is a required parameter.
class BEMatterTableViewController: UITableViewController {
@IBOutlet weak var ssid: UITextField!
@IBOutlet weak var password: UITextField!
var deviceTypeModel: ThingMatterDeviceDiscoveriedType?
private var isSuccess = false
var deviceList: [ThingSmartActivatorDeviceModel] = []
/// UI
override func viewDidLoad() {
super.viewDidLoad()
title = "Matter"
startSearchMatter()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
stopConfigWifi()
}
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
}()
private func startSearchMatter () {
let homeId = (Home.current?.homeId)!
self.typeModel.spaceId = homeId;
self.discovery.startSearch([self.typeModel])
}
}
extension BEMatterTableViewController: ThingSmartActivatorSearchDelegate {
func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didFindDevice device: ThingSmartActivatorDeviceModel?, error errorModel: ThingSmartActivatorErrorModel?) {
if device != nil {
SVProgressHUD.show(withStatus: "Search device: (\(device?.name ?? ""))")
deviceList.append(device!)
tableView.reloadData()
return
}
}
}
The pairing parameters differ depending on the type of Matter devices. For example, Wi-Fi devices require the name and password of the Wi-Fi network, while Thread devices require the ID of the gateway. See the example code.
class BEMatterTableViewController: UITableViewController {
// The code for device search is omitted here.
private func startBindMatter(with deviceModel:ThingSmartActivatorDeviceModel) -> Void {
let homeId = (Home.current?.homeId)!
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:[deviceModel])
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) {
startBindMatter(with: deviceList[indexPath.row])
}
}
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)
}
}
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 ?? "")")
}
}
If an error message indicates that the device is already bound, it must be unbound before being paired again. Using the FAQ UI BizBundle, guide users to the FAQ and Feedback module for submitting an unbinding request.
Add the dependency ThingSmartHelpCenterBizBundle
in the podfile
, and then run the command pod update
to pull the code.
target 'TuyaAppSDKSample-iOS-Swift' do
use_modular_headers!
pod 'SVProgressHUD'
pod 'SGQRCode', '~> 4.1.0'
# Build and get ThingSmartCryption from iot.tuya.com
# After purchasing the App SDK official edition, you need to build the SDK again on the Tuya Developer Platform and integrate this new SDK.
# ./ indicates that the `ios_core_sdk.tar.gz` file will be extracted in the same directory as the `podfile`.
# To change the storage location, modify `path` to your desired location.
pod 'ThingSmartCryption', :path => '../ios_core_sdk'
pod 'ThingSmartHomeKit', '~> 5.2.0'
pod 'ThingSmartBusinessExtensionKit'
pod 'ThingSmartBusinessExtensionKitBLEExtra'
# Add FAQ UI BizBundle
pod 'ThingSmartHelpCenterBizBundle'
end
If the error code is ThingSmartActivatorDiscoveryErrorDeviceAlreadyBound
, you can trigger the unbinding logic.
extension BEBLEModeViewController: ThingSmartActivatorActiveDelegate {
func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
if (errorModel != nil) {
if let error = errorModel?.error {
let errorCode = (error as NSError).code
if (errorCode == ThingSmartActivatorDiscoveryErrorDeviceAlreadyBound.rawValue) {
let impl = ThingSmartBizCore.sharedInstance().service(of:ThingFeedBackProtocol.self) as? ThingFeedBackProtocol
impl?.gotFeedBackViewController?(withHdType: 8, deviceName:errorModel?.deviceModel?.name, hdId: errorModel?.deviceModel?.devId, uuid: errorModel?.deviceModel?.uniqueID, region:ThingSmartUser.sharedInstance().regionCode, withoutRefresh: true)
}
}
SVProgressHUD.showError(withStatus: NSLocalizedString("Failed to Activate BLE Device", comment: ""))
return
}
}
}
You can enable or disable the strong binding feature on the Tuya Developer Platform.
Log in to the Tuya Developer Platform.
Select a product and click Develop in the Operation column.
In the Function Definition step, scroll down to Advanced Functions and find Device Binding Mode. Toggle it on or off as desired.
Device binding is restricted by both the PID and the app. You can specify the app that a PID can be bound with and the device that an app can be connected to. A device can only be bound when both the app and the device meet the restriction. By default, there are no restrictions for both the PID and app, allowing them to be connected freely.
The error code ThingSmartActivatorDiscoveryErrorAPPUnsupportProduct
indicates that special biding rules exist. To modify the rules, submit a service ticket.
func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
if (errorModel != nil) {
if let error = errorModel?.error {
let errorCode = (error as NSError).code
if (errorCode == ThingSmartActivatorDiscoveryErrorAPPUnsupportProduct.rawValue) {
//
}
}
SVProgressHUD.showError(withStatus: NSLocalizedString("Failed to Activate BLE Device", comment: ""))
return
}
}
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback