TSMusic
Manage music playback and file operations on watch devices, including fetching music lists, pushing tracks, deleting individual or all tracks, controlling playback, and adjusting volume.
Prerequisites
- Device must be connected and authenticated
- For push operations, music files must exist locally and be readable
- Check
isSupportMusicPushbefore calling music file management APIs, includingdeleteAllMusicsWithCompletion: - All callbacks execute on the main thread
Data Models
TSMusicModel
Represents music information and playback state on the watch device.
| Property | Type | Description |
|---|---|---|
filePath | NSString * | Local file path of the music file, required for push operations |
title | NSString * | Music track title; for device file management, the complete device file name including its extension |
artist | NSString * | Artist or performer name, max 64 bytes, displayed on device |
duration | NSTimeInterval | Total duration in seconds, used for progress calculation |
currentTime | NSTimeInterval | Current playback position in seconds, range 0 to duration |
playbackStatus | TSMusicPlaybackStatus | Current playback state (stopped, playing, or paused) |
Helper methods:
| Method | Description |
|---|---|
resolvedFileName | Returns title when present, otherwise filePath.lastPathComponent; does not verify file existence |
hasReadableLocalFile | Checks whether filePath points to an existing readable local regular file; format and Provider restrictions remain separate |
Enumerations
TSMusicPlaybackStatus
Defines playback status of music on the watch device.
| Value | Description |
|---|---|
TSMusicPlaybackStatusStopped | Music is stopped |
TSMusicPlaybackStatusPlaying | Music is playing |
TSMusicPlaybackStatusPaused | Music is paused |
Callback Types
TSMusicListBlock
typedef void (^TSMusicListBlock)(`NSArray<TSMusicModel *>` *_Nullable musics, NSError *_Nullable error);
Callback for music list retrieval operations.
| Parameter | Type | Description |
|-----------|------|-------------|
| `musics` | `NSArray<TSMusicModel *> *` | Array of music models, empty if retrieval fails |
| `error` | `NSError *` | Error information if failed, nil if successful |
## API Reference
### Check music capabilities
```objc
- (BOOL)isSupportMusicPush;
- (BOOL)isSupportMusicControl;
Music-file management and remote playback control are independent capabilities. Check the matching flag before presenting either feature.
Fetch music storage information
- (void)fetchMusicStorageSpace:(nullable TSStorageSpaceResultBlock)completion;
Returns the device storage snapshot used for music files. This API requires music-push support.
Fetch all music from device
- (void)fetchAllMusics:(nonnull TSMusicListBlock)completion;
Retrieves all music tracks currently stored on the watch device.
| Parameter | Type | Description |
|---|---|---|
completion | TSMusicListBlock | Callback with array of all music models |
Example:
[musicInterface fetchAllMusics:^(`NSArray<TSMusicModel *>` *musics, NSError *error) {
if (error) {
TSLog(@"Failed to fetch musics: %@", error.localizedDescription);
return;
}
TSLog(@"Found %lu musics", (unsigned long)musics.count);
for (TSMusicModel *music in musics) {
TSLog(@"Music: %@ by %@", music.title, music.artist);
}
}];
Delete music from device
- (void)deleteMusic:(`TSMusicModel *`)music completion:(nullable TSCompletionBlock)completion;
Removes a specific music track from the watch device.
| Parameter | Type | Description |
|---|---|---|
music | TSMusicModel * | Music model to delete; title is preferred, with filePath.lastPathComponent used as fallback |
completion | TSCompletionBlock | Callback with success status and error info |
Example:
TSMusicModel *musicToDelete = [[TSMusicModel alloc] init];
musicToDelete.title = @"music_123.mp3";
[musicInterface deleteMusic:musicToDelete completion:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"Music deleted successfully");
} else {
TSLog(@"Failed to delete music: %@", error.localizedDescription);
}
}];
Delete all music from device
- (void)deleteAllMusicsWithCompletion:(nullable TSCompletionBlock)completion;
Deletes every music track managed by TSMusicInterface without deleting recordings or other media files. An already empty music collection is treated as a successful, idempotent operation. A non-nil callback is invoked exactly once on the main thread; passing nil ignores the result but still starts deletion.
If another music push or deletion operation is active, the request fails with a busy error without joining or canceling that operation. A failure may occur after some tracks have already been deleted, so refresh with fetchAllMusics: before presenting the result or retrying.
| Parameter | Type | Description |
|---|---|---|
completion | TSCompletionBlock | Completion callback; success is YES only when no managed music tracks remain |
Example:
if ([musicInterface isSupportMusicPush]) {
[musicInterface deleteAllMusicsWithCompletion:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"All music deleted");
} else {
TSLog(@"Deletion incomplete: %@; refresh the music list", error.localizedDescription);
}
}];
}
Push music to device
- (void)pushMusic:(`TSMusicModel *`)music
progress:(nullable TSFileTransferProgressBlock)progress
success:(nullable TSFileTransferSuccessBlock)success
failure:(nullable TSFileTransferFailureBlock)failure;
Transfers a music track to the watch device with progress tracking.
| Parameter | Type | Description |
|---|---|---|
music | TSMusicModel * | Music model with valid filePath pointing to music file |
progress | TSFileTransferProgressBlock | Called multiple times with transfer progress (0-100) |
success | TSFileTransferSuccessBlock | Called when push completes successfully |
failure | TSFileTransferFailureBlock | Called when push fails or is canceled |
Example:
TSMusicModel *music = [[TSMusicModel alloc] init];
music.filePath = @"/path/to/music.mp3";
music.title = @"Song Title";
music.artist = @"Artist Name";
[musicInterface pushMusic:music
progress:^(NSInteger progress, TSFileTransferStatus status) {
TSLog(@"Push progress: %ld%%", (long)progress);
} success:^(TSFileTransferStatus status) {
TSLog(@"Music pushed successfully");
} failure:^(TSFileTransferStatus status, NSError *error) {
TSLog(@"Push failed: %@", error.localizedDescription);
}];
Cancel music push
- (void)cancelPushMusic:(nullable TSCompletionBlock)completion;
Cancels the currently ongoing music push operation and cleans up temporary files.
| Parameter | Type | Description |
|---|---|---|
completion | TSCompletionBlock | Callback with cancellation status |
Example:
[musicInterface cancelPushMusic:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"Push operation canceled");
} else {
TSLog(@"Failed to cancel: %@", error.localizedDescription);
}
}];
Play music
- (void)playMusic:(nullable TSCompletionBlock)completion;
Sends play command to start or resume music playback on the device.
| Parameter | Type | Description |
|---|---|---|
completion | TSCompletionBlock | Callback with command execution status |
Example:
[musicInterface playMusic:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"Playback started");
}
}];
Pause music
- (void)pauseMusic:(nullable TSCompletionBlock)completion;
Sends pause command to pause current music playback on the device.
| Parameter | Type | Description |
|---|---|---|
completion | TSCompletionBlock | Callback with command execution status |
Example:
[musicInterface pauseMusic:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"Playback paused");
}
}];
Play next track
- (void)playNextMusic:(nullable TSCompletionBlock)completion;
Sends command to skip to the next music track on the device.
| Parameter | Type | Description |
|---|---|---|
completion | TSCompletionBlock | Callback with command execution status |
Example:
[musicInterface playNextMusic:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"Skipped to next track");
}
}];
Play previous track
- (void)playPreviousMusic:(nullable TSCompletionBlock)completion;
Sends command to skip to the previous music track on the device.
| Parameter | Type | Description |
|---|---|---|
completion | TSCompletionBlock | Callback with command execution status |
Example:
[musicInterface playPreviousMusic:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"Skipped to previous track");
}
}];
Increase volume
- (void)increaseVolume:(nullable TSCompletionBlock)completion;
Increases device volume by one step as determined by device firmware.
| Parameter | Type | Description |
|---|---|---|
completion | TSCompletionBlock | Callback with command execution status |
Example:
[musicInterface increaseVolume:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"Volume increased");
}
}];
Decrease volume
- (void)decreaseVolume:(nullable TSCompletionBlock)completion;
Decreases device volume by one step as determined by device firmware.
| Parameter | Type | Description |
|---|---|---|
completion | TSCompletionBlock | Callback with command execution status |
Example:
[musicInterface decreaseVolume:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"Volume decreased");
}
}];
Mute device
- (void)muteVolume:(nullable TSCompletionBlock)completion;
Mutes the device while preserving current volume level for later restoration.
| Parameter | Type | Description |
|---|---|---|
completion | TSCompletionBlock | Callback with command execution status |
Example:
[musicInterface muteVolume:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"Device muted");
}
}];
Unmute device
- (void)unmuteVolume:(nullable TSCompletionBlock)completion;
Unmutes the device and restores the volume level active before muting.
| Parameter | Type | Description |
|---|---|---|
completion | TSCompletionBlock | Callback with command execution status |
Example:
[musicInterface unmuteVolume:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"Device unmuted");
}
}];
Set volume to specific value
- (void)setVolume:(NSInteger)volume completion:(nullable TSCompletionBlock)completion;
Sets device volume to a specific value between 0 and 100.
| Parameter | Type | Description |
|---|---|---|
volume | NSInteger | Target volume value, range [0, 100], values outside range are clamped |
completion | TSCompletionBlock | Callback with command execution status |
Example:
[musicInterface setVolume:50 completion:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"Volume set to 50");
}
}];
Important Notes
- All callbacks execute on the main thread; perform UI updates directly without additional dispatch
- Check
isSupportMusicPushbefore using music file management APIs - Music file paths must be valid and readable when pushing; verify file existence before operations
- Only one push operation can be active at a time; cancel ongoing operations before starting new ones
- For single-track deletion,
resolvedFileNamemust produce the complete device file name including its extension deleteAllMusicsWithCompletion:affects music tracks only. Empty state succeeds; after failure, refresh the list because deletion may be partial- Volume values are automatically clamped to [0, 100] range; no validation errors for out-of-range input
- Playback control commands (play, pause, next, previous) require music to be present on device
- Mute state is independent of volume level; unmute restores the previous volume without requiring explicit set