Last Updated on : 2025-04-11 06:10:05download
Smart Config Plus is an optimized version of combo device pairing, designed to enhance bulk pairing speed.
Add dependencies to the Podfile, including the base dependency ThingSmartBusinessExtensionKit
and the Bluetooth implementation dependency ThingSmartBusinessExtensionKitBLEExtra
, as shown below:
source 'https://github.com/tuya/tuya-pod-specs.git'
platform :ios, '11.0'
target 'Your_Project_Name' do
# Build and get ThingSmartCryption from the Tuya Developer Platform (https://platform.tuya.com).
# After the official edition is purchased, rebuild the SDK on the Tuya Developer Platform and integrate it into your project.
# The dot slash (./) notation represents that the files that are obtained after ios_core_sdk.tar.gz is extracted are put at a sibling directory as podfile.
# To use another directory, change the path to your desired directory.
pod 'ThingSmartCryption', :path =>'./'
pod 'ThingSmartHomeKit'
pod 'ThingSmartBusinessExtensionKit'
# Bluetooth implementation layer
pod 'ThingSmartBusinessExtensionKitBLEExtra'
end
When the device pairing service is initialized, register the pairing type.
Device type | Pairing type | Model |
---|---|---|
Bluetooth LE or combo device | ThingSmartActivatorTypeBle | ThingSmartActivatorTypeBleModel |
Bluetooth pairing model
/// Ble
@interface ThingSmartActivatorTypeBleModel : ThingSmartActivatorTypeModel
/// Ble Scan Type
@property (nonatomic, assign) ThingActivatorBleScanType scanType;
/// Home ID
@property (nonatomic, assign) long long spaceId;
/// Pairing token (only used for Bluetooth fallback pairing)
@property (nonatomic, strong) NSString *token;
/// Wi-Fi name
@property (nonatomic, strong) NSString *ssid;
/// Wi-Fi password
@property (nonatomic, strong) NSString *password;
/// Gateway ID
@property (nonatomic, copy) NSString *gwDevId;
/// Active Type
@property (nonatomic, assign) ThingActivatorBleActiveType activeType;
@end
For Smart Config Plus pairing, select ThingActivatorBleActiveTypeBatch
for activeType
.
Registration method
/// Initialize pairing types
/// @param typeList Pairing types
- (void)registerWithActivatorList:(NSArray<ThingSmartActivatorTypeModel *>*)typeList;
Parameters
Parameter | Description |
---|---|
typeList | The list of pairing types. |
The SDK gets a pairing token from the cloud before it can start the pairing process. The token is valid for 10 minutes and expires immediately after the device is paired. A new token must be generated if the device needs to be paired again.
API description
- (void)getTokenWithHomeId:(long long)homeId
success:(ThingSuccessString)success
failure:(ThingFailureError)failure;
Parameters
Parameter | Description |
---|---|
homeId | The ID of the home with which the device is bound. |
success | The success callback. A pairing token is returned. |
failure | The failure callback. An error message is returned. |
Pass in the registered typeList
to start searching.
API description
/// Start searching
/// @param typeList Pairing types
- (void)startSearch:(NSArray <ThingSmartActivatorTypeModel *>*)typeList;
Parameters
Parameter | Description |
---|---|
typeList | The list of pairing types. |
API description
/// Stop searching
/// @param typeList Pairing types
/// @param clearCache Whether to clear the cache
- (void)stopSearch:(NSArray <ThingSmartActivatorTypeModel *>*)typeList clearCache:(BOOL)clearCache;
Parameters
Parameter | Description |
---|---|
typeList | The list of pairing types. |
clearCache | Specifies whether to clear the cache search result. |
After the Bluetooth device is discovered, the callback returns the device information. If the operation fails, the callback returns the error message.
API description
/// Device search callback
/// @param service Search instance
/// @param type Pairing 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;
Parameters
Parameter | Description |
---|---|
service | The pairing service. |
type | The pairing type. |
device | The discovered device. The device model is returned on success. nil is returned on failure. |
errorModel | When searching for Bluetooth devices, this model will not be returned in cases where no devices are found or when the search times out. |
API description
/// Activate devices with a single pairing type
/// @param type Pairing type
/// @param deviceList Devices to be activated
- (void)startActive:(ThingSmartActivatorTypeModel *)type deviceList:(NSArray<ThingSmartActivatorDeviceModel *>*)deviceList;
Parameters
Parameter | Description |
---|---|
type | Pairing type |
deviceList | The list of devices to be activated. Currently, only one device is supported. |
Unlike single combo device pairing, bulk pairing requires to set the activeType
property of ThingSmartActivatorTypeBleModel
to batch
. Also, a token shall be set to join the network.
/// Special attention: Batch pairing requires this setting, otherwise only the standard single device pairing will proceed.
typeModel.activeType = ThingActivatorBleActiveType.batch
typeModel.token = token
API description
/// Stop activating devices
/// @param typeList Array of pairing types
/// @param clearCache Whether to clear the cache
- (void)stopActive:(NSArray <ThingSmartActivatorTypeModel *>*)typeList clearCache:(BOOL)clearCache;
Parameters
Parameter | Description |
---|---|
typeList | Pairing type |
clearCache | Specifies whether to clear the cache search result. |
API description
// Device pairing result callback
/// @param service Device pairing implementation object
/// @param type Pairing type
/// @param devices Devices being paired
/// @param errorModel Error encountered during pairing
- (void)activatorService:(id<ThingSmartActivatorActiveProtocol>)service
activatorType:(ThingSmartActivatorTypeModel *)type
didReceiveDevices:(nullable NSArray<ThingSmartActivatorDeviceModel *> *)devices
error:(nullable ThingSmartActivatorErrorModel *)errorModel;
Parameters
Parameter | Description |
---|---|
service | The pairing service. |
type | Pairing type |
devices | The activated device. |
errorModel | This model is returned if pairing fails or times out. nil is returned on success. |
class BEDualModePlusViewController: UIViewController {
// MARK: - Properties
private var deviceList: [ThingSmartActivatorDeviceModel] = []
private var cellModelList: [BEDeviceCellModel] = []
private var isSuccess = false
private lazy var discovery: ThingSmartActivatorDiscovery = {
let discovery = ThingSmartActivatorDiscovery()
discovery.register(withActivatorList: [self.typeModel])
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
}()
private lazy var typeModel: ThingSmartActivatorTypeBleModel = {
let type = ThingSmartActivatorTypeBleModel()
type.type = ThingSmartActivatorType.ble
type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.ble)
type.timeout = 120
/// Special attention: Batch pairing requires this setting, otherwise only the standard single device pairing will proceed.
type.activeType = ThingActivatorBleActiveType.batch
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
}()
// MARK: - Actions
@objc private func searchTapped() {
deviceList.removeAll()
tableView.reloadData()
discovery.startSearch([self.typeModel])
SVProgressHUD.show(withStatus: "Searching for devices...")
}
// MARK: - Private Methods
private func stopConfiguring() {
if !isSuccess {
SVProgressHUD.dismiss()
}
discovery.stopSearch([self.typeModel], clearCache: true)
discovery.stopActive([self.typeModel], clearCache: true)
discovery.removeDelegate(self)
}
}
// MARK: - ThingSmartActivatorSearchDelegate
extension BEDualModePlusViewController: ThingSmartActivatorSearchDelegate {
func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didFindDevice device: ThingSmartActivatorDeviceModel?, error errorModel: ThingSmartActivatorErrorModel?) {
if errorModel != nil {
SVProgressHUD.showError(withStatus:"Faulty device")
return
}
guard let device = device else { return }
switch device.deviceModelType {
case ThingSearchDeviceModelTypeBle:
print("Please use Dual Mode to pair \(device.uniqueID)")
SVProgressHUD.dismiss()
case ThingSearchDeviceModelTypeBleWifi:
if !deviceList.contains(where: { $0.uniqueID == device.uniqueID }) {
deviceList.append(device)
tableView.reloadData()
}
SVProgressHUD.dismiss()
default:
break
}
}
func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didUpdateDevice device: ThingSmartActivatorDeviceModel) {
let devicecellModel = cellModel(for: device)
updateDeviceStatus(for: devicecellModel)
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
ssidTextField.resignFirstResponder()
passwordTextField.resignFirstResponder()
let deviceCellModel = cellModelList[indexPath.row]
guard let ssid = ssidTextField.text, !ssid.isEmpty else {
SVProgressHUD.showError(withStatus: "Please enter the WiFi name")
return
}
guard let password = passwordTextField.text, !password.isEmpty else {
SVProgressHUD.showError(withStatus: "Please enter the WiFi password")
return
}
if typeModel.token.isEmpty {
ThingSmartActivator.sharedInstance()?.getTokenWithHomeId(typeModel.spaceId, success: { [weak self] (token) in
guard let self = self else { return }
typeModel.token = token ?? ""
self.startConfiguringNetwork(deviceCellModel: deviceCellModel, indexPath: indexPath)
}, failure: { (error) in
})
} else {
startConfiguringNetwork(deviceCellModel: deviceCellModel, indexPath: indexPath)
}
}
private func startConfiguringNetwork(deviceCellModel: BEDeviceCellModel, indexPath: IndexPath) {
deviceCellModel.deviceStatus = "Adding"
typeModel.ssid = ssidTextField.text ?? ""
typeModel.password = passwordTextField.text ?? ""
updateDeviceStatus(for: deviceCellModel)
// Start pairing
discovery.startActive(typeModel, deviceList: [deviceCellModel.deviceModel])
// discovery.startActive(typeModel, deviceList: deviceList)
tableView.deselectRow(at: indexPath, animated: true)
}
// MARK: - ThingSmartActivatorActiveDelegate
extension BEDualModePlusViewController: ThingSmartActivatorActiveDelegate {
func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
if let errorModel = errorModel {
let cellModel = cellModel(for: errorModel.deviceModel!)
cellModel.deviceStatus = "Failed"
updateDeviceStatus(for: cellModel)
return
}
guard let device = devices?.first else { return }
let cellModel = cellModel(for: device)
cellModel.deviceStatus = "succeed"
updateDeviceStatus(for: cellModel)
isSuccess = true
}
}
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback