dial
---
sidebar_position: 5
title: Dial
---
# Dial
The Dial module provides comprehensive watch face management for peripheral devices, including operations to push, delete, switch, and monitor watch faces. It supports built-in watch faces, cloud watch faces, and custom watch faces with full lifecycle management capabilities.
## Prerequisites
- Device must be connected and authenticated
- For cloud watch faces, internet connectivity is required
- Device firmware must support watch face operations
- Sufficient storage space on device for new watch faces
## Data Models
### TSDialModel
General watch face information model used for device watch face operations.
| Property | Type | Description |
|----------|------|-------------|
| `dialId` | `NSString *` | Unique identifier for the watch face |
| `dialName` | `NSString *` | Display name shown to users |
| `dialType` | `TSDialType` | Type of watch face (BuiltIn, Customer, or Cloud) |
| `isCurrent` | `BOOL` | YES if currently active on device |
| `locationIndex` | `UInt8` | Position index where watch face is stored |
| `version` | `NSString *` | Version number for update management |
| `filePath` | `NSString *` | Local file system path to resources |
### TSCustomDial
Custom watch face creation model for pushing custom watch faces to device.
| Property | Type | Description |
|----------|------|-------------|
| `dialId` | `NSString *` | Unique identifier for custom watch face |
| `dialName` | `NSString *` | Display name for custom watch face |
| `dialType` | `TSCustomDialType` | Type (SingleImage, MultipleImage, or Video) |
| `templateFilePath` | `NSString *` | Local path to template bin file |
| `previewImageItem` | `TSCustomDialItem *` | Preview image item for UI display |
| `resourceItems` | `NSArray<TSCustomDialItem *> *` | Array of background image/video items |
### TSCustomDialItem
Single item in a watch face containing resource and time configuration.
| Property | Type | Description |
|----------|------|-------------|
| `dialType` | `TSCustomDialType` | Item resource type (SingleImage, MultipleImage, or Video) |
| `videoLocalPath` | `NSString *` | Local path to video file (for video type) |
| `resourceImage` | `UIImage *` | Background image (for image types) |
| `dialTime` | `TSCustomDialTime *` | Time display configuration |
### TSCustomDialTime
Time display configuration for custom watch face items.
| Property | Type | Description |
|----------|------|-------------|
| `timeImage` | `UIImage *` | Time style image (takes priority over timeImagePath) |
| `timeImagePath` | `NSString *` | Local path to time style image file |
| `timePosition` | `TSDialTimePosition` | Position on watch face (Top, Bottom, Left, Right, etc.) |
| `timeRect` | `CGRect` | Custom rectangle area for time display |
| `timeColor` | `UIColor *` | Color for time display text |
| `style` | `TSDialTimeStyle` | Style enumeration (Style1 through Style7) |
## Enumerations
### TSDialType
Watch face type enumeration.
| Value | Name | Description |
|-------|------|-------------|
| `0` | `eTSDialTypeBuiltIn` | Built-in watch face from device |
| `1` | `eTSDialTypeCustomer` | Custom watch face created by user |
| `2` | `eTSDialTypeCloud` | Watch face downloaded from cloud |
### TSCustomDialType
Custom watch face resource type enumeration.
| Value | Name | Description |
|-------|------|-------------|
| `1` | `eTSCustomDialSingleImage` | Single image-based custom watch face |
| `2` | `eTSCustomDialMultipleImage` | Multiple images-based custom watch face |
| `3` | `eTSCustomDialVideo` | Video-based custom watch face |
### TSDialTimePosition
Time display position enumeration.
| Value | Name | Description |
|-------|------|-------------|
| `0` | `eTSDialTimePositionTop` | Top position |
| `1` | `eTSDialTimePositionBottom` | Bottom position |
| `2` | `eTSDialTimePositionLeft` | Left position |
| `3` | `eTSDialTimePositionRight` | Right position |
| `4` | `eTSDialTimePositionTopLeft` | Top-left corner |
| `5` | `eTSDialTimePositionBottomLeft` | Bottom-left corner |
| `6` | `eTSDialTimePositionTopRight` | Top-right corner |
| `7` | `eTSDialTimePositionBottomRight` | Bottom-right corner |
| `8` | `eTSDialTimePositionCenter` | Center position |
### TSDialPushResult
Watch face push operation result enumeration.
| Value | Name | Description |
|-------|------|-------------|
| `0` | `eTSDialPushResultStart` | Push operation started |
| `0` | `eTSDialPushResultProgress` | Push in progress |
| `1` | `eTSDialPushResultSuccess` | Push completed successfully |
| `2` | `eTSDialPushResultFailed` | Push operation failed |
### TSDialTimeStyle
Time display style enumeration.
| Value | Name | Description |
|-------|------|-------------|
| `0` | `eTSDialTimeStyleNone` | No style |
| `1` | `eTSDialTimeStyle1` | Style 1 |
| `2` | `eTSDialTimeStyle2` | Style 2 |
| `3` | `eTSDialTimeStyle3` | Style 3 |
| `4` | `eTSDialTimeStyle4` | Style 4 |
| `5` | `eTSDialTimeStyle5` | Style 5 |
| `6` | `eTSDialTimeStyle6` | Style 6 |
| `7` | `eTSDialTimeStyle7` | Style 7 |
## Callback Types
### TSDialCompletionBlock
```objc
typedef void (^TSDialCompletionBlock)(TSDialPushResult result, NSError *_Nullable error);
Watch face operation completion callback invoked multiple times during push process.
TSDialProgressBlock
typedef void(^TSDialProgressBlock)(TSDialPushResult result, NSInteger progress);
Watch face push progress callback reporting current progress (0-100).
TSDialListBlock
typedef void (^TSDialListBlock)(`NSArray<TSDialModel *>` *_Nullable dials, NSError *_Nullable error);
Watch face list callback returning array of watch face models.
TSDialSpaceBlock
typedef void (^TSDialSpaceBlock)(NSInteger remainSpace, NSError *_Nullable error);
Watch face storage space callback returning remaining space in bytes.
TSDialWidgetsBlock
typedef void (^TSDialWidgetsBlock)(NSDictionary *_Nullable widgets, NSError *_Nullable error);
Widget list callback for Fw series devices returning widget information dictionary.
API Reference
Fetch current watch face
- (void)fetchCurrentDial:(void (^)(TSDialModel *_Nullable dial,
NSError *_Nullable error))completion;
Retrieves information about the currently active watch face on the device.
| Parameter | Type | Description |
|---|---|---|
completion | void (^)(TSDialModel *, NSError *) | Callback with current watch face model |
Example:
[dialInterface fetchCurrentDial:^(TSDialModel *dial, NSError *error) {
if (error) {
TSLog(@"Failed to fetch current dial: %@", error.localizedDescription);
return;
}
TSLog(@"Current dial: %@", dial.dialName);
}];
Fetch all watch faces
- (void)fetchAllDials:(TSDialListBlock)completion;
Retrieves information about all watch faces on the device including local, custom, and cloud watch faces.
| Parameter | Type | Description |
|---|---|---|
completion | TSDialListBlock | Callback with array of all watch face models |
Example:
[dialInterface fetchAllDials:^(`NSArray<TSDialModel *>` *dials, NSError *error) {
if (error) {
TSLog(@"Failed to fetch dials: %@", error.localizedDescription);
return;
}
TSLog(@"Total dials: %lu", (unsigned long)dials.count);
for (TSDialModel *dial in dials) {
TSLog(@"Dial: %@ (Type: %lu)", dial.dialName, (unsigned long)dial.dialType);
}
}];
Switch current watch face
- (void)switchToDial:(`TSDialModel *`)dial
completion:(nullable void(^)(BOOL isSuccess, NSError *_Nullable error))completion;
Switches the device's current watch face to the specified dial.
| Parameter | Type | Description |
|---|---|---|
dial | TSDialModel * | Watch face model to switch to |
completion | void (^)(BOOL, NSError *) | Completion callback |
Example:
TSDialModel *targetDial = [[TSDialModel alloc] init];
targetDial.dialId = @"dial_001";
[dialInterface switchToDial:targetDial completion:^(BOOL isSuccess, NSError *error) {
if (isSuccess) {
TSLog(@"Successfully switched to dial");
} else {
TSLog(@"Failed to switch dial: %@", error.localizedDescription);
}
}];
Generate custom watch face ID
- (nonnull `NSString *`)generateCustomDialIdWithType:(TSCustomDialType)dialType;
Generates a unique identifier for a custom watch face.
| Parameter | Type | Description |
|---|---|---|
dialType | TSCustomDialType | Custom watch face type (SingleImage, MultipleImage, or Video) |
Example:
NSString *customDialId = [dialInterface generateCustomDialIdWithType:eTSCustomDialSingleImage];
TSLog(@"Generated custom dial ID: %@", customDialId);
Push cloud watch face
- (void)installDownloadedCloudDial:(`TSDialModel *`)dial
progressBlock:(nullable TSDialProgressBlock)progressBlock
completion:(nullable TSDialCompletionBlock)completion;
Pushes a cloud watch face to the device with progress tracking.
| Parameter | Type | Description |
|---|---|---|
dial | TSDialModel * | Cloud watch face model with valid dialId and eTSDialTypeCloud type |
progressBlock | TSDialProgressBlock | Optional progress callback (0-100) |
completion | TSDialCompletionBlock | Optional completion callback |
Example:
TSDialModel *cloudDial = [[TSDialModel alloc] init];
cloudDial.dialId = @"cloud_dial_123";
cloudDial.dialType = eTSDialTypeCloud;
[dialInterface installDownloadedCloudDial:cloudDial
progressBlock:^(TSDialPushResult result, NSInteger progress) {
TSLog(@"Push progress: %ld%%", (long)progress);
} completion:^(TSDialPushResult result, NSError *error) {
if (result == eTSDialPushResultSuccess) {
TSLog(@"Cloud dial pushed successfully");
} else if (result == eTSDialPushResultFailed) {
TSLog(@"Failed to push cloud dial: %@", error.localizedDescription);
}
}];
Push custom watch face
- (void)installCustomDial:(`TSCustomDial *`)customDial
progressBlock:(nullable TSDialProgressBlock)progressBlock
completion:(nullable TSDialCompletionBlock)completion;
Pushes a custom watch face to the device with progress tracking.
| Parameter | Type | Description |
|---|---|---|
customDial | TSCustomDial * | Custom watch face model |
progressBlock | TSDialProgressBlock | Optional progress callback |
completion | TSDialCompletionBlock | Optional completion callback |
Example:
TSCustomDial *customDial = [[TSCustomDial alloc] init];
customDial.dialId = [dialInterface generateCustomDialIdWithType:eTSCustomDialSingleImage];
customDial.dialName = @"My Custom Dial";
customDial.dialType = eTSCustomDialSingleImage;
customDial.templateFilePath = @"/path/to/template.bin";
TSCustomDialItem *item = [[TSCustomDialItem alloc] init];
item.dialType = eTSCustomDialSingleImage;
item.resourceImage = [UIImage imageNamed:@"dial_background"];
item.dialTime = [[TSCustomDialTime alloc] init];
item.dialTime.timePosition = eTSDialTimePositionTop;
item.dialTime.timeImage = [UIImage imageNamed:@"time_style"];
customDial.resourceItems = @[item];
[dialInterface installCustomDial:customDial
progressBlock:^(TSDialPushResult result, NSInteger progress) {
TSLog(@"Custom dial push progress: %ld%%", (long)progress);
} completion:^(TSDialPushResult result, NSError *error) {
if (result == eTSDialPushResultSuccess) {
TSLog(@"Custom dial installed successfully");
}
}];
Delete watch face
- (void)deleteDial:(`TSDialModel *`)dial
completion:(nullable void(^)(BOOL isSuccess, NSError *_Nullable error))completion;
Deletes a watch face from the device by identifier.
| Parameter | Type | Description |
|---|---|---|
dial | TSDialModel * | Watch face model to delete |
completion | void (^)(BOOL, NSError *) | Completion callback |
Example:
TSDialModel *dialToDelete = [[TSDialModel alloc] init];
dialToDelete.dialId = @"custom_dial_001";
[dialInterface deleteDial:dialToDelete completion:^(BOOL isSuccess, NSError *error) {
if (isSuccess) {
TSLog(@"Dial deleted successfully");
} else {
TSLog(@"Failed to delete dial: %@", error.localizedDescription);
}
}];
Fetch remaining storage space
- (void)fetchWatchFaceRemainingStorageSpace:(nullable TSDialSpaceBlock)completion;
Retrieves remaining storage space available for watch faces on the device.
| Parameter | Type | Description |
|---|---|---|
completion | TSDialSpaceBlock | Callback with remaining space in bytes |
Example:
[dialInterface fetchWatchFaceRemainingStorageSpace:^(NSInteger remainSpace, NSError *error) {
if (error) {
TSLog(@"Failed to fetch storage space: %@", error.localizedDescription);
return;
}
TSLog(@"Remaining space: %ld bytes", (long)remainSpace);
}];
Register watch face change notification
- (void)registerDialDidChangedBlock:(void (^)(`NSArray<TSDialModel *>` *_Nullable allDials))completion;
Registers a callback to monitor watch face changes on the device.
| Parameter | Type | Description |
|---|---|---|
completion | void (^)(NSArray<TSDialModel *> *) | Callback invoked when watch faces change |
Example:
[dialInterface registerDialDidChangedBlock:^(`NSArray<TSDialModel *>` *allDials) {
if (allDials) {
TSLog(@"Watch faces changed. Total: %lu", (unsigned long)allDials.count);
for (TSDialModel *dial in allDials) {
if (dial.isCurrent) {
TSLog(@"Current dial: %@", dial.dialName);
}
}
}
}];
Cancel push operation
- (void)cancelPushDial:(TSCompletionBlock)completion;
Cancels an ongoing watch face push operation.
| Parameter | Type | Description |
|---|---|---|
completion | TSCompletionBlock | Completion callback |
Example:
[dialInterface cancelPushDial:^(BOOL isSuccess, NSError *error) {
if (isSuccess) {
TSLog(@"Push operation cancelled");
}
}];
Get maximum built-in watch faces
- (NSInteger)maxInnerDialCount;
Returns the maximum number of built-in watch faces supported by the device.
Example:
NSInteger maxBuiltIn = [dialInterface maxInnerDialCount];
TSLog(@"Max built-in dials: %ld", (long)maxBuiltIn);
Get maximum cloud watch faces
- (NSInteger)maxCanPushDialCount;
Returns the maximum number of cloud watch faces that can be stored on the device.
Example:
NSInteger maxCloud = [dialInterface maxCanPushDialCount];
TSLog(@"Max cloud dials: %ld", (long)maxCloud);
Check slideshow support
- (BOOL)isSupportSlideshowDial;
Checks if device supports slideshow (photo album) watch faces.
Example:
if ([dialInterface isSupportSlideshowDial]) {
TSLog(@"Device supports slideshow dials");
}
Check video support
- (BOOL)isSupportVideoDial;
Checks if device supports video watch faces.
Example:
if ([dialInterface isSupportVideoDial]) {
TSLog(@"Device supports video dials");
}
Check dial component support
- (BOOL)isSupportDialComponent;
Checks if device supports dial components.
Example:
if ([dialInterface isSupportDialComponent]) {
TSLog(@"Device supports dial components");
}
Get maximum video duration
- (NSInteger)maxVideoDialDuration;
Returns the maximum video duration in seconds for video watch faces.
Example:
NSInteger maxDuration = [dialInterface maxVideoDialDuration];
TSLog(@"Max video duration: %ld seconds", (long)maxDuration);
Request supported widgets
- (void)requestSupportWidgetsFromPeripheralCompletion:(TSDialWidgetsBlock)completion;
Fetches the list of supported widgets from Fw series devices.
| Parameter | Type | Description |
|---|---|---|
completion | TSDialWidgetsBlock | Callback with widget information dictionary |
Example:
[dialInterface requestSupportWidgetsFromPeripheralCompletion:^(NSDictionary *widgets, NSError *error) {
if (error) {
TSLog(@"Failed to fetch widgets: %@", error.localizedDescription);
return;
}
TSLog(@"Supported widgets: %@", widgets);
}];
Generate preview image
- (void)previewImageWith:(`UIImage *`)originImage
timeImage:(`UIImage *`)timeImage
timePosition:(TSDialTimePosition)timePosition
maxKBSize:(CGFloat)maxKBSize
completion:(void (^)(UIImage *_Nullable, NSError *_Nullable))completion;
Generates a watch face preview image by compositing time image onto background image.
| Parameter | Type | Description |
|---|---|---|
originImage | UIImage * | Background image for watch face |
timeImage | UIImage * | Time display image to composite |
timePosition | TSDialTimePosition | Position for time image |
maxKBSize | CGFloat | Maximum file size in KB |
completion | void (^)(UIImage *, NSError *) | Callback with generated preview image |
Example:
UIImage *background = [UIImage imageNamed:@"dial_bg"];
UIImage *timeStyle = [UIImage imageNamed:@"time_style"];
[dialInterface previewImageWith:background
timeImage:timeStyle
timePosition:eTSDialTimePositionTop
maxKBSize:300
completion:^(UIImage *previewImage, NSError *error) {
if (error) {
TSLog(@"Failed to generate preview: %@", error.localizedDescription);
return;
}
TSLog(@"Preview image generated successfully");
}];
Generate preview from dial item
- (void)previewImageWithDialItem:(`TSCustomDialItem *`)dialItem
maxKBSize:(CGFloat)maxKBSize
completion:(void (^)(UIImage *_Nullable, NSError *_Nullable))completion;
Generates a watch face preview image from a custom dial item.
| Parameter | Type | Description |
|---|---|---|
dialItem | TSCustomDialItem * | Custom dial item with background and time configuration |
maxKBSize | CGFloat | Maximum file size in KB (default 300 if ≤0) |
completion | void (^)(UIImage *, NSError *) | Callback with generated preview image |
Example:
TSCustomDialItem *dialItem = [[TSCustomDialItem alloc] init];
dialItem.dialType = eTSCustomDialSingleImage;
dialItem.resourceImage = [UIImage imageNamed:@"dial_background"];
dialItem.dialTime = [[TSCustomDialTime alloc] init];
dialItem.dialTime.timeImage = [UIImage imageNamed:@"time_style"];
dialItem.dialTime.timePosition = eTSDialTimePositionTop;
[dialInterface previewImageWithDialItem:dialItem
maxKBSize:300
completion:^(UIImage *previewImage, NSError *error) {
if (error) {
TSLog(@"Failed to generate preview: %@", error.localizedDescription);
return;
}
TSLog(@"Preview generated from dial item");
}];
Important Notes
-
Use
TSDialModelfor device watch face information and cloud watch face operations; useTSCustomDialfor creating and pushing custom watch faces. -
Image size requirements must be strictly met: background images must match
TSPeripheralScreen.screenSize, and preview images must matchTSPeripheralScreen.dialPreviewSize. -
Only one watch face change callback can be registered at a time; new registration replaces the previous one.
-
Built-in watch faces cannot be deleted; only custom and cloud watch faces can be removed.
-
Check device capabilities with
isSupportSlideshowDial,isSupportVideoDial, andisSupportDialComponentbefore implementing related features. -
Progress callbacks during push operations may be called multiple times; completion callbacks are also called multiple times with different result states.
-
For custom watch faces, ensure
templateFilePathpoints to a valid bin file andresourceItemsarray is not empty. -
Time position priority: if
timeRectis set (notCGRectZero), it takes priority overtimePosition. -
Video watch faces have duration limits; check
maxVideoDialDurationbefore pushing video content. -
Widget operations are only available for Fw series devices; other device types will return nil.