Skip to main content

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 isSupportMusicPush before calling music file management APIs, including deleteAllMusicsWithCompletion:
  • All callbacks execute on the main thread

Data Models​

TSMusicModel​

Represents music information and playback state on the watch device.

PropertyTypeDescription
filePathNSString *Local file path of the music file, required for push operations
titleNSString *Music track title; for device file management, the complete device file name including its extension
artistNSString *Artist or performer name, max 64 bytes, displayed on device
durationNSTimeIntervalTotal duration in seconds, used for progress calculation
currentTimeNSTimeIntervalCurrent playback position in seconds, range 0 to duration
playbackStatusTSMusicPlaybackStatusCurrent playback state (stopped, playing, or paused)

Helper methods:

MethodDescription
resolvedFileNameReturns title when present, otherwise filePath.lastPathComponent; does not verify file existence
hasReadableLocalFileChecks 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.

ValueDescription
TSMusicPlaybackStatusStoppedMusic is stopped
TSMusicPlaybackStatusPlayingMusic is playing
TSMusicPlaybackStatusPausedMusic 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.

ParameterTypeDescription
completionTSMusicListBlockCallback 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.

ParameterTypeDescription
musicTSMusicModel *Music model to delete; title is preferred, with filePath.lastPathComponent used as fallback
completionTSCompletionBlockCallback 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.

ParameterTypeDescription
completionTSCompletionBlockCompletion 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.

ParameterTypeDescription
musicTSMusicModel *Music model with valid filePath pointing to music file
progressTSFileTransferProgressBlockCalled multiple times with transfer progress (0-100)
successTSFileTransferSuccessBlockCalled when push completes successfully
failureTSFileTransferFailureBlockCalled 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.

ParameterTypeDescription
completionTSCompletionBlockCallback 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.

ParameterTypeDescription
completionTSCompletionBlockCallback 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.

ParameterTypeDescription
completionTSCompletionBlockCallback 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.

ParameterTypeDescription
completionTSCompletionBlockCallback 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.

ParameterTypeDescription
completionTSCompletionBlockCallback 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.

ParameterTypeDescription
completionTSCompletionBlockCallback 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.

ParameterTypeDescription
completionTSCompletionBlockCallback 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.

ParameterTypeDescription
completionTSCompletionBlockCallback 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.

ParameterTypeDescription
completionTSCompletionBlockCallback 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.

ParameterTypeDescription
volumeNSIntegerTarget volume value, range [0, 100], values outside range are clamped
completionTSCompletionBlockCallback with command execution status

Example:

[musicInterface setVolume:50 completion:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"Volume set to 50");
}
}];

Important Notes​

  1. All callbacks execute on the main thread; perform UI updates directly without additional dispatch
  2. Check isSupportMusicPush before using music file management APIs
  3. Music file paths must be valid and readable when pushing; verify file existence before operations
  4. Only one push operation can be active at a time; cancel ongoing operations before starting new ones
  5. For single-track deletion, resolvedFileName must produce the complete device file name including its extension
  6. deleteAllMusicsWithCompletion: affects music tracks only. Empty state succeeds; after failure, refresh the list because deletion may be partial
  7. Volume values are automatically clamped to [0, 100] range; no validation errors for out-of-range input
  8. Playback control commands (play, pause, next, previous) require music to be present on device
  9. Mute state is independent of volume level; unmute restores the previous volume without requiring explicit set