Last Updated on : 2023-05-22 06:38:28
Device Details UI BizBundle supports the following features:
Add the components of the Device Details UI BizBundle to the Podfile and run the command pod update
.
source "https://github.com/tuya/tuya-pod-specs"
source 'https://cdn.cocoapods.org/'
platform :ios, '11.0'
target 'your_target_name' do
# Adds the Device Details UI BizBundle.
pod 'TuyaSmartDeviceDetailBizBundle'
end
The UI BizBundle supports the upload of device icons. To implement this feature, the permissions on the system album and camera must be granted. This requires specific declarations of privacy and permissions from Apple. Add the following permission declaration to info.plist
of your project:
<!-- Album -->
<key>NSPhotoLibraryUsageDescription</key>
<string>Authorizes the app to access the album of the mobile phone</string>
<!-- Camera -->
<key>NSCameraUsageDescription</key>
<string>Authorizes the app to access the camera of the mobile phone</string>
Create the configuration file deviceDetailConfig.json
in the main project. If the file already exists, skip the creation.
Add the following content to deviceDetailConfig.json
:
[
{
"name": "headerSection",
"items": [
{
"cellType": "header"
},{
"cellType": "device_info"
},{
"cellType": "net_setting"
},{
"cellType":"group_edit_devices"
}
]
},{
"name": "offLineWarnSection",
"header": {
"cellType":"section_off_line_warn"
},
"items": [
{
"cellType" : "off_line_warn"
}
]
},{
"name": "otherSection",
"header": {
"cellType":"section_other"
},
"items": [
{
"cellType":"bind_multi_control_link"
},
{
"cellType":"group_create"
},
{
"cellType":"help_and_feedback"
},
{
"cellType":"add_icon_to_home_screen"
},
{
"cellType":"show_infrared_gateway_sub_device"
},
{
"cellType":"check_device_network"
},
{
"cellType":"check_firmware_update"
}
]
},{
"name": "footerSection",
"items": [
{
"cellType":"footer"
}
],
"margin": {
"top": 16
}
}
]
Customize device details.
The sequence of the item
parameter in the deviceDetail
array determines the sequence in which each item
is displayed on the device details page. If item
is removed, the associated device feature will also be removed from the device details page.
Item of deviceDetail |
Device feature |
---|---|
header | View and modify the device icon, device name, and location. |
device_info | Device information |
net_setting | Display backup Wi-Fi networks. |
off_line_warn | Notify users of devices getting offline. |
group_edit_devices | Modify a group |
group_create | Create a group |
help_and_feedback | Provide FAQ and feedback. FAQ UI BizBundle must be additionally integrated. |
check_firmware_update | Check for firmware updates. OTA UI BizBundle must be additionally integrated. |
add_icon_to_home_screen | Add shortcuts to the home screen. |
show_infrared_gateway_sub_device | Show remote controls. |
footer | Remove devices. |
TYSmartHomeDataProtocol
is deprecated and TYFamilyProtocol
is recommended.
/**
To use this API method to get the current home data, you must use `'updateCurrentHomeId:' Api` of the protocol when the current home ID is updated.
Returns the current home. If the current user does not have a home, `nil` is returned.
@return TuyaSmartHome
*/
- (TuyaSmartHome *)getCurrentHome;
ObjC:
#import <TuyaSmartBizCore/TuyaSmartBizCore.h>
#import <TYModuleServices/TYSmartHomeDataProtocol.h>
- (void)initCurrentHome {
// Registers the protocol to be implemented.
[[TuyaSmartBizCore sharedInstance] registerService:@protocol(TYSmartHomeDataProtocol) withInstance:self];
}
// Implements the protocol method.
- (TuyaSmartHome *)getCurrentHome {
TuyaSmartHome *home = [TuyaSmartHome homeWithHomeId:@"Current home ID"];
return home;
}
Swift:
import TuyaSmartDeviceKit
class TYMessageCenterTest: NSObject,TYSmartHomeDataProtocol{
func test() {
TuyaSmartBizCore.sharedInstance().registerService(TYSmartHomeDataProtocol.self, withInstance: self)
}
func getCurrentHome() -> TuyaSmartHome! {
let home = TuyaSmartHome.init(homeId: 111)
return home
}
}
Check for firmware updates. OTA UI BizBundle must be additionally integrated.
Provide FAQ and feedback. FAQ UI BizBundle must be additionally integrated.
Manage group devices. Group Management UI BizBundle must be additionally integrated.
Method | Parameter |
---|---|
Navigate to the network detection page | The device ID. |
Navigate to device details by means of push | TuyaSmartDeviceModel/TuyaSmartGroupModel |
Check whether to display infrared sub-devices | devId, spaceId |
Check whether displaying infrared sub-devices is enabled. | devId, spaceId |
Display the notification of infrared sub-device status changes | - |
API description
/// Navigates to the page of network detection.
/// @param devId The device ID.
- (void)gotoDeviceDetailNetworkViewControllerWithDeviceId:(NSString *)devId;
/// Navigates to device details by means of push.
/// @param device The device.
/// @param group The group if any. It is optional.
- (void)gotoDeviceDetailDetailViewControllerWithDevice:(TuyaSmartDeviceModel *)device group:(TuyaSmartGroupModel *)group;
@optional
/// Checks whether to display infrared sub-devices.
/// @param devId The device ID. If a non-infrared gateway or sub-device is passed in, `YES` is returned.
/// @param spaceId The space ID.
/// @return The return value. Valid values: `YES`: display. `NO`: not display.
- (BOOL)getInfraredDisplayStatusWithDevId:(nullable NSString *)devId spaceId:(long long)spaceId;
@optional
/// Checks whether displaying infrared sub-devices is enabled.
/// @param devId The device ID.
/// @param spaceId The space ID.
/// @return The return value. Valid values: `YES`: display. `NO`: not display.
- (BOOL)cacheOfInfraredDisplayStatusWithDevId:(nullable NSString *)devId spaceId:(long long)spaceId;
@optional
/// Displays the notification of infrared sub-device status changes.
- (nullable NSNotificationName)subDeviceDisplayStatusChangeNotificationName;
ObjC:
#import <TuyaSmartBizCore/TuyaSmartBizCore.h>
#import <TYModuleServices/TYDeviceDetailProtocol.h>
id<TYDeviceDetailProtocol> impl = [[TuyaSmartBizCore sharedInstance] serviceOfProtocol:@protocol(TYDeviceDetailProtocol)];
// Navigates to the page of network detection.
[impl gotoDeviceDetailNetworkViewControllerWithDeviceId:@"Device ID"];
// Navigate to device details by means of push
// For a device, `new TuyaSmartDevice` is called.
TuyaSmartDevice * device = [TuyaSmartDevice deviceWithDeviceId:@"Device ID"]
[impl gotoDeviceDetailDetailViewControllerWithDevice: device.deviceModel group: nil];
// For a group, `new TuyaSmartGroup` is called.
TuyaSmartGroup * group = [TuyaSmartDevice groupWithGroupId:@"Group ID"]
[impl gotoDeviceDetailDetailViewControllerWithDevice: nil group: group.deviceModel];
Swift:
let impl = TuyaSmartBizCore.sharedInstance().service(of: TYDeviceDetailProtocol.self) as? TYDeviceDetailProtocol
// Navigates to the page of network detection.
impl?.gotoDeviceDetailNetworkViewController(withDeviceId: "Device ID")
// Navigate to device details by means of push
// For a device, `new TuyaSmartDevice` is called.
let device = TuyaSmartDevice.init(deviceId: "vdevo160888044089994")
impl?.gotoDeviceDetailDetailViewController(withDevice: device?.deviceModel, group: nil)
// For a group, `new TuyaSmartGroup` is called.
let group = TuyaSmartGroup.init(groupId: "Group ID")
impl?.gotoDeviceDetailDetailViewController(withDevice: nil, group: group?.groupModel)
Add to Home Screen: This feature allows users to create a bookmark on the home screen. This bookmark works as the shortcut of a device panel. After users tap this bookmark, your app is evoked and users are navigated to the target device panel. To enable this feature, perform the following steps:
Add add_icon_to_home_screen
to deviceDetailConfig.json
. Otherwise, this feature is unavailable.
Set appScheme
in the file ty_custom_config.json
. In the following example, you need to replace the default value Your appScheme
with another value.
{
"config": {
...
"appScheme": "Your appScheme"
},
...
}
Add the value of appScheme
in the file ty_custom_config.json
to URL Scheme
. In the preceding example, this default value is Your appScheme
. It must be replaced with another value.
Process routing events in AppDelegate
:
ObjC:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options {
if ([[url.scheme lowercaseString] isEqualToString:@"oralcaretest"]) {
NSDictionary *params = [self dictionaryFromQuery:url.query usingEncoding:NSUTF8StringEncoding];
NSString *host = url.host;
if ([host isEqualToString:@"panelEx"]) {
id <TYPanelProtocol> impl = [[TuyaSmartBizCore sharedInstance] serviceOfProtocol:@protocol(TYPanelProtocol)];
TuyaSmartDevice *device = [TuyaSmartDevice deviceWithDeviceId:params[@"devId"]?: @""];
[impl getPanelViewControllerWithDeviceModel:device.deviceModel initialProps:nil contextProps:nil completionHandler:^(__kindof UIViewController * _Nullable panelViewController, NSError * _Nullable error) {
if (error) {
NSLog(@"Load error: %@", error);
}
}];
}
return YES;
}
return NO;
}
- (NSDictionary *)dictionaryFromQuery:(NSString *)query usingEncoding:(NSStringEncoding)encoding {
if (!([query isKindOfClass:[NSString class]] && query.length > 0)) {
return nil;
}
NSCharacterSet *delimiterSet = [NSCharacterSet characterSetWithCharactersInString:@"&;"];
NSMutableDictionary* pairs = [NSMutableDictionary dictionary];
NSScanner* scanner = [[NSScanner alloc] initWithString:query];
while (![scanner isAtEnd]) {
NSString* pairString = nil;
[scanner scanUpToCharactersFromSet:delimiterSet intoString:&pairString];
[scanner scanCharactersFromSet:delimiterSet intoString:NULL];
NSArray* kvPair = [pairString componentsSeparatedByString:@"="];
if (kvPair.count == 2) {
NSString* key = [[kvPair objectAtIndex:0]
stringByReplacingPercentEscapesUsingEncoding:encoding];
NSString* value = [[kvPair objectAtIndex:1]
stringByReplacingPercentEscapesUsingEncoding:encoding];
[pairs setObject:value forKey:key];
}
}
return [NSDictionary dictionaryWithDictionary:pairs];
}
Swift:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if let scheme = url.scheme, scheme.lowercased() == "oralcaretest" {
let params = self.params(from: url.query, .utf8)
if let host = url.host, host == "panelEx", let devId = params?["devId"] as? String, let device = TuyaSmartDevice(deviceId: devId) {
let impl: TYPanelProtocol? = TuyaSmartBizCore.sharedInstance().service(of: TYPanelProtocol.self) as? TYPanelProtocol
impl?.getPanelViewController(with: device.deviceModel, initialProps: nil, contextProps: nil, completionHandler: { vc, error in
if error != nil {
print(error!.localizedDescription)
}else{
print("push the vc")
}
})
}
return true
}
return false
}
func params(from query: String?, _ encoding: String.Encoding) -> Dictionary<String, Any>? {
guard let queryString = query, queryString.count > 0 else {
return nil
}
let set = CharacterSet(charactersIn: "&;")
var pairs = Dictionary<String, Any>()
let scanner = Scanner(string: queryString)
while !scanner.isAtEnd {
var pairString: NSString? = ""
scanner.scanUpToCharacters(from: set, into: &pairString)
scanner.scanCharacters(from: set, into: nil)
if let kvPair = pairString?.components(separatedBy: "="), kvPair.count == 2 {
let key: String = kvPair.first!.removingPercentEncoding!
let value: String = kvPair.last!
pairs[key] = value
}
}
return pairs
}
You can enable device feature icon editing and allow users to select album photos or take photos with camera. For this purpose, configure ty_custom_config.json
with the following options:
Set is_enable_device_icon_edit
to true
, so the feature icon of selecting album photos and taking photos with camera for common devices can be edited.
Set is_enable_group_icon_edit
to true
, so the feature icon of selecting album photos and taking photos with camera for group devices can be edited.
{
"config": {
...
"is_enable_device_icon_edit": true,
"is_enable_group_icon_edit": true
},
...
}
By default, the SDK does not show the feature that allows users to hide location data from device details. To show the feature, set is_support_home_manager
to true
in ty_custom_config.json
.
{
"config": {
...
"is_support_home_manager": true,
},
...
}
Specific features can be implemented with the configuration file deviceDetailConfig.json
. You can add the custom parameter type
to deviceDetail
in deviceDetailConfig.json
.
The value of type
must start with c_
. For example, c_test_insert
and c_test_async_insert
can be added.
[
{
"name": "headerSection",
"items": [
{
"cellType": "header"
},{
"cellType": "device_info"
},{
"cellType": "net_setting"
},{
"cellType":"group_edit_devices"
}
]
},{
"name": "offLineWarnSection",
"header": {
"cellType":"section_off_line_warn"
},
"items": [
{
"cellType" : "off_line_warn"
}
]
},{
"name": "otherSection",
"header": {
"cellType":"section_other"
},
"items": [
{
"cellType":"bind_multi_control_link"
},
{
"cellType":"group_create"
},
{
"cellType":"help_and_feedback"
},
{
"cellType":"add_icon_to_home_screen"
},
{
"cellType":"show_infrared_gateway_sub_device"
},
{
"cellType":"check_device_network"
},
{
"cellType":"check_firmware_update"
},
{
"cellType":"c_test_insert"
},
{
"cellType":"c_test_async_insert"
}
]
},{
"name": "footerSection",
"items": [
{
"cellType":"footer"
}
],
"margin": {
"top": 16
}
}
]
/// Implements the synchronous callback. `insertDevMenuItemBlock` returns the callback when device details are refreshed. `type` is equivalent to `cellType` in the configuration file.
-(void)insertDevMenuItem:(InsertDevMenuItemBlock) insertDevMenuItemBlock customType:(NSString *)type;
//@param type The custom type specified in `configList.json`.
//@param device The device model.
//@param group The group model. If `group` is `nil`, device data is returned. Otherwise, group data is returned.
//@return The object that follows the protocol `TYDeviceDetailCustomMenuModel`. If `nil` is returned, this type of item is not displayed.
typedef id<TYDeviceDetailCustomMenuModel> _Nullable (^InsertDevMenuItemBlock)(NSString* _Nonnull type,
TuyaSmartDeviceModel* _Nullable device,
TuyaSmartGroupModel* _Nullable group);
/// Implements the asynchronous callback. `insertDevMenuItemAsyncBlock` returns the callback when device details are refreshed. `type` is equivalent to `cellType` in the configuration file.
-(void)insertDevMenuItemAsync:(InsertDevMenuItemAsyncBlock) insertDevMenuItemAsyncBlock customType:(NSString *)type;
// Inserts the asynchronous operation to process the item. At the end of the operation, call `complete(id<TYDeviceDetailCustomMenuMode>)`. The result data is returned to the device details module and the list is refreshed.
typedef void (^InsertDevMenuItemAsyncBlock)(NSString* _Nonnull type,
TuyaSmartDeviceModel* _Nullable device,
TuyaSmartGroupModel* _Nullable group,
InsertDevMenuItemComplete _Nonnull complete);
Model
classObjC:
// Customizes a class that adopts the protocol `TYDeviceDetailCustomMenuModel`.
@interface CustomMenuModel : NSObject<TYDeviceDetailCustomMenuModel>
/// The title.
@property (nonatomic,copy) NSString *title;
/// The subtitle.
@property (nonatomic,copy) NSString *detail;
@end
@implementation CustomMenuModel
@end
Swift:
class CustomMenuModel: NSObject, TYDeviceDetailCustomMenuModel{
var title : String?
var detail : String?
}
ObjC:
id<TYDeviceDetailProtocol> impl = [[TuyaSmartBizCore sharedInstance] serviceOfProtocol:@protocol(TYDeviceDetailProtocol)];
[impl insertDevMenuItem:^ id<TYDeviceDetailCustomMenuModel> (NSString * _Nonnull type, TuyaSmartDeviceModel * _Nonnull device, TuyaSmartGroupModel * _Nonnull group) {
if ([type isEqualToString:@"c_test_insert"]) {
CustomMenuModel *model = [CustomMenuModel new];
if (group) { // If `group` is `nil`, device data is returned. Otherwise, group data is returned.
model.title = type;
model.detail = @"group";
}else{
model.title = type;
model.detail = @"device";
}
return model;
}
return nil;
} customType:@"c_test_insert"];
[impl insertDevMenuItemAsync:^(NSString * _Nonnull type, TuyaSmartDeviceModel * _Nonnull device, TuyaSmartGroupModel * _Nonnull group, InsertDevMenuItemComplete _Nonnull complete) {
if ([type isEqualToString:@"c_test_async_insert"]) {
// The time-consuming operation.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
CustomMenuModel *model = [CustomMenuModel new];
if (group) { // If `group` is `nil`, device data is returned. Otherwise, group data is returned.
model.title = type;
model.detail = @"group";
}else{
model.title = type;
model.detail = @"device";
}
complete(model);
});
}
} customType:@"c_test_insert"];
Swift:
let impl = TuyaSmartBizCore.sharedInstance().service(of: TYDeviceDetailProtocol.self) as? TYDeviceDetailProtocol
impl?.insertDevMenuItem({ (type, deviceModel, groupModel) -> TYDeviceDetailCustomMenuModel? in
if type == "c_test_insert" {// If `group` is `nil`, device data is returned. Otherwise, group data is returned.
let model = CustomMenuModel.init()
if groupModel != nil {
model.title = type
model.detail = "group"
}else{
model.title = type
model.detail = "device"
}
return model;
}
return nil;
} , customType: "c_test_insert")
impl?.insertDevMenuItemAsync({ (type, deviceModel, groupModel, complete) in
if type == "c_test_async_insert" {
// The time-consuming operation.
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
let model = CustomMenuModel.init()
if groupModel != nil {
model.title = type
model.detail = "group"
}else{
model.title = type
model.detail = "device"
}
complete(model);
}
}
} , customType: "c_test_async_insert");
ObjC:
id<TYDeviceDetailProtocol> impl = [[TuyaSmartBizCore sharedInstance] serviceOfProtocol:@protocol(TYDeviceDetailProtocol)];
[impl clickMenuItem: ^(NSString * _Nonnull type, TuyaSmartDeviceModel * _Nonnull device, TuyaSmartGroupModel * _Nonnull group) {
NSLog(@"clickItem: type:%@",type);
}];
Swift:
let impl = TuyaSmartBizCore.sharedInstance().service(of: TYDeviceDetailProtocol.self) as? TYDeviceDetailProtocol
impl?.clickMenuItem({ (type, deviceModel, groupModel) in
print("clickItem: type:"+type);
})
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback