Sleep
The TSSleep module provides comprehensive sleep data management and analysis capabilities for TopStepComKit iOS SDK. It enables synchronization of detailed sleep data from wearable devices, including night sleep, daytime naps, and sleep stage information (Awake, Light, Deep, and REM stages). The module offers both raw sleep segment data for fine-grained analysis and daily aggregated sleep summaries with customizable statistics rules.
Prerequisites
- TopStepComKit iOS SDK initialized and connected to a compatible wearable device
- Device must support sleep monitoring functionality
- Proper permissions granted for health data access
- Valid time intervals provided in Unix timestamp (seconds) format
Data Models
TSSleepDetailItem
Represents a single sleep stage segment with stage type, timing, and belonging date information.
| Property | Type | Description |
|---|---|---|
stage | TSSleepStage | Sleep stage type (Awake/Light/Deep/REM) |
belongingDate | NSTimeInterval | Unix timestamp of 00:00:00 of the day this sleep belongs to. Sleep data uses 20:00 as day boundary [20:00→20:00) |
startTime | NSTimeInterval | Unix timestamp of segment start time (inherited from TSHealthValueItem) |
duration | NSTimeInterval | Duration of this sleep stage segment in seconds (inherited from TSHealthValueItem) |
TSSleepSummary
Statistical summary of sleep data including durations, percentages, and quality metrics.
| Property | Type | Description |
|---|---|---|
startTime | NSTimeInterval | Unix timestamp of sleep start time |
endTime | NSTimeInterval | Unix timestamp of sleep end time |
duration | NSTimeInterval | Total duration from start to end time in seconds |
totalSleepDuration | NSTimeInterval | Total effective sleep time excluding awake periods (seconds) |
qualityScore | UInt8 | Sleep quality score (0-100) based on duration, deep sleep percentage, and awakenings |
awakeDuration | NSTimeInterval | Total awake duration during sleep period (seconds) |
lightSleepDuration | NSTimeInterval | Total light sleep duration (seconds) |
deepSleepDuration | NSTimeInterval | Total deep sleep duration (seconds) |
remDuration | NSTimeInterval | Total REM sleep duration (seconds) |
awakePercentage | UInt8 | Awake time percentage relative to total sleep duration (0-100) |
lightSleepPercentage | UInt8 | Light sleep percentage relative to total sleep duration (0-100) |
deepSleepPercentage | UInt8 | Deep sleep percentage relative to total sleep duration (0-100) |
remPercentage | UInt8 | REM sleep percentage relative to total sleep duration (0-100) |
awakeCount | UInt16 | Number of awake episodes |
lightSleepCount | UInt16 | Number of light sleep episodes |
deepSleepCount | UInt16 | Number of deep sleep episodes |
remCount | UInt16 | Number of REM episodes |
TSSleepSegment
Represents a continuous sleep segment with period type, summary statistics, and detailed stage items.
| Property | Type | Description |
|---|---|---|
periodType | TSSleepPeriodType | Sleep period type (Night or Daytime) |
summary | TSSleepSummary * | Statistical summary of this sleep segment |
detailItems | NSArray<TSSleepDetailItem *> * | Detailed sleep stage items in chronological order |
TSSleepDailyModel
Daily sleep data model representing one sleep calendar day with segments and raw items.
| Property | Type | Description |
|---|---|---|
statisticsRule | TSSleepStatisticsRule | Statistics rule used for this sleep record |
dailySummary | TSSleepSummary * | Overall daily sleep summary after processing |
rawSleepItems | NSArray<TSSleepDetailItem *> * | Array of raw sleep detail items synced from device before processing |
nightSleeps | NSArray<TSSleepSegment *> * | One or more continuous night-sleep segments for this day |
daytimeSleeps | NSArray<TSSleepSegment *> * | All daytime sleep segments classified for this day |
Enumerations
TSSleepStage
Defines different stages of sleep according to AASM standards.
| Value | Description |
|---|---|
TSSleepStageAwake | Subject is awake during sleep period |
TSSleepStageLight | Light sleep phase (N1 and N2 stages) |
TSSleepStageDeep | Deep sleep phase (N3 stage, slow-wave sleep) |
TSSleepStageREM | Rapid Eye Movement sleep phase (dream sleep) |
TSSleepPeriodType
Defines the period of sleep based on data header time.
| Value | Description |
|---|---|
TSSleepPeriodTypeNight | Night sleep period (20:00-09:00) |
TSSleepPeriodTypeDaytime | Daytime sleep period (09:00-20:00) |
TSSleepStatisticsRule
Sleep statistics rule type determining how sleep data is processed and categorized.
| Value | Description |
|---|---|
TSSleepStatisticsRuleWithoutNap | Basic rule without nap support: sensor active 20:00-12:00, all sleep treated as night sleep |
TSSleepStatisticsRuleWithNap | With nap support: sensor active 24h, distinguishes night/day sleep |
TSSleepStatisticsRuleLongestNight | Uses longest continuous night sleep segment (20:00-08:00), valid naps counted |
TSSleepStatisticsRuleLongestOnly | No distinction between night/day, uses longest continuous sleep segment only |
Callback Types
Raw Data Completion
void (^)(NSArray<TSSleepDetailItem *> *_Nullable sleepItems, NSError *_Nullable error)
Callback for raw sleep segment data synchronization.
| Parameter | Type | Description |
|---|---|---|
sleepItems | NSArray<TSSleepDetailItem *> * | Array of raw sleep detail items, or nil if error occurred |
error | NSError * | Error information if synchronization failed, nil on success |
Daily Data Completion
void (^)(NSArray<TSSleepDailyModel *> *_Nullable sleepModel, NSError *_Nullable error)
Callback for daily aggregated sleep data synchronization.
| Parameter | Type | Description |
|---|---|---|
sleepModel | NSArray<TSSleepDailyModel *> * | Array of daily sleep models, or nil if error occurred |
error | NSError * | Error information if synchronization failed, nil on success |
API Reference
Check REM Sleep Support
Determine if the device supports REM sleep stage detection and recording.
- (BOOL)isSupportREMSleep;
**Parameters**
None
**Return Value**
| Type | Description |
|---|---|
BOOL | YES if device supports REM sleep stage detection, NO otherwise |
**Code Example**
id<TSSleepInterface> sleepInterface = /* obtained from kit */;
BOOL supportsREM = [sleepInterface isSupportREMSleep];
if (supportsREM) {
TSLog(@"Device supports REM sleep detection");
} else {
TSLog(@"Device does not support REM sleep detection");
}
Synchronize Raw Sleep Segments From Start Time
Synchronize raw sleep segments starting from a specified time point.
- (void)syncRawDataFromStartTime:(NSTimeInterval)startTime
completion:(nonnull void (^)(NSArray<TSSleepDetailItem *> *_Nullable sleepItems, NSError *_Nullable error))completion;
**Parameters**
| Name | Type | Description |
|---|---|---|
startTime | NSTimeInterval | Unix timestamp (seconds) of the starting point |
completion | void (^)(NSArray<TSSleepDetailItem *> *, NSError *) | Callback block returning sleep items array or error |
**Code Example**
id<TSSleepInterface> sleepInterface = /* obtained from kit */;
// Create a start time: 30 days ago
NSTimeInterval startTime = [[NSDate dateWithTimeIntervalSinceNow:-30*24*60*60] timeIntervalSince1970];
[sleepInterface syncRawDataFromStartTime:startTime
completion:^(NSArray<TSSleepDetailItem *> *sleepItems, NSError *error) {
if (error) {
TSLog(@"Failed to sync raw sleep data: %@", error.localizedDescription);
return;
}
TSLog(@"Successfully synced %lu raw sleep items", (unsigned long)sleepItems.count);
for (TSSleepDetailItem *item in sleepItems) {
NSString *stageName = @[@"Awake", @"Light", @"Deep", @"REM"][item.stage];
TSLog(@"Sleep stage: %@, Duration: %.0f seconds", stageName, item.duration);
}
}];
Synchronize Raw Sleep Segments Within Time Range
Synchronize raw sleep segments within a specified time range.
- (void)syncRawDataFromStartTime:(NSTimeInterval)startTime
endTime:(NSTimeInterval)endTime
completion:(nonnull void (^)(NSArray<TSSleepDetailItem *> *_Nullable sleepItems, NSError *_Nullable error))completion;
**Parameters**
| Name | Type | Description |
|---|---|---|
startTime | NSTimeInterval | Unix timestamp (seconds) of range start (inclusive) |
endTime | NSTimeInterval | Unix timestamp (seconds) of range end (exclusive). Range is [startTime, endTime) |
completion | void (^)(NSArray<TSSleepDetailItem *> *, NSError *) | Callback block returning sleep items array or error |
**Code Example**
id<TSSleepInterface> sleepInterface = /* obtained from kit */;
// Get sleep data for the last 7 days
NSTimeInterval endTime = [[NSDate date] timeIntervalSince1970];
NSTimeInterval startTime = endTime - (7 * 24 * 60 * 60);
[sleepInterface syncRawDataFromStartTime:startTime
endTime:endTime
completion:^(NSArray<TSSleepDetailItem *> *sleepItems, NSError *error) {
if (error) {
TSLog(@"Failed to sync raw sleep data: %@", error.localizedDescription);
return;
}
NSTimeInterval totalSleep = 0;
for (TSSleepDetailItem *item in sleepItems) {
if (item.stage != TSSleepStageAwake) {
totalSleep += item.duration;
}
}
TSLog(@"Total sleep in last 7 days: %.0f hours", totalSleep / 3600);
}];
Synchronize Daily Aggregated Sleep Data From Start Time
Synchronize daily aggregated sleep summaries starting from a specified date.
- (void)syncDailyDataFromStartTime:(NSTimeInterval)startTime
completion:(nonnull void (^)(NSArray<TSSleepDailyModel *> *_Nullable sleepModel, NSError *_Nullable error))completion;
**Parameters**
| Name | Type | Description |
|---|---|---|
startTime | NSTimeInterval | Unix timestamp (seconds) of the starting day |
completion | void (^)(NSArray<TSSleepDailyModel *> *, NSError *) | Callback block returning daily sleep models array or error |
**Code Example**
id<TSSleepInterface> sleepInterface = /* obtained from kit */;
// Get daily sleep data from 60 days ago
NSTimeInterval startTime = [[NSDate dateWithTimeIntervalSinceNow:-60*24*60*60] timeIntervalSince1970];
[sleepInterface syncDailyDataFromStartTime:startTime
completion:^(NSArray<TSSleepDailyModel *> *sleepModels, NSError *error) {
if (error) {
TSLog(@"Failed to sync daily sleep data: %@", error.localizedDescription);
return;
}
for (TSSleepDailyModel *model in sleepModels) {
TSSleepSummary *summary = model.dailySummary;
TSLog(@"Date: %@, Total Sleep: %.0f hours, Quality: %u, Deep Sleep: %u%%",
[NSDate dateWithTimeIntervalSince1970:model.startTime],
summary.totalSleepDuration / 3600,
summary.qualityScore,
summary.deepSleepPercentage);
}
}];
Synchronize Daily Aggregated Sleep Data Within Time Range
Synchronize daily aggregated sleep summaries within a specified date range.
- (void)syncDailyDataFromStartTime:(NSTimeInterval)startTime
endTime:(NSTimeInterval)endTime
completion:(nonnull void (^)(NSArray<TSSleepDailyModel *> *_Nullable sleepModel, NSError *_Nullable error))completion;
**Parameters**
| Name | Type | Description |
|---|---|---|
startTime | NSTimeInterval | Unix timestamp (seconds) of range start day (inclusive) |
endTime | NSTimeInterval | Unix timestamp (seconds) of range end day (exclusive). Range is [startTime, endTime) |
completion | void (^)(NSArray<TSSleepDailyModel *> *, NSError *) | Callback block returning daily sleep models array or error |
**Code Example**
id<TSSleepInterface> sleepInterface = /* obtained from kit */;
// Get sleep data for a specific month
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *now = [NSDate date];
NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth
fromDate:now];
components.day = 1;
NSDate *monthStart = [calendar dateFromComponents:components];
NSDateComponents *nextMonthComponents = [NSDateComponents new];
nextMonthComponents.month = 1;
NSDate *monthEnd = [calendar dateByAddingComponents:nextMonthComponents toDate:monthStart options:0];
NSTimeInterval startTime = [monthStart timeIntervalSince1970];
NSTimeInterval endTime = [monthEnd timeIntervalSince1970];
[sleepInterface syncDailyDataFromStartTime:startTime
endTime:endTime
completion:^(NSArray<TSSleepDailyModel *> *sleepModels, NSError *error) {
if (error) {
TSLog(@"Failed to sync daily sleep data: %@", error.localizedDescription);
return;
}
NSUInteger goodSleepDays = 0;
for (TSSleepDailyModel *model in sleepModels) {
if (model.dailySummary.qualityScore >= 80) {
goodSleepDays++;
}
}
TSLog(@"Days with good sleep (score >= 80): %lu out of %lu",
(unsigned long)goodSleepDays,
(unsigned long)sleepModels.count);
}];
Process Raw Sleep Items Into Daily Models
Process raw sleep detail items into per-day models using a specified statistics rule.
+ (nullable NSArray<TSSleepDailyModel *> *)processWithStatisticsRule:(TSSleepStatisticsRule)statisticsRule
rawItems:(NSArray<TSSleepDetailItem *> *)rawItems;
**Parameters**
| Name | Type | Description |
|---|---|---|
statisticsRule | TSSleepStatisticsRule | Statistics rule to use for processing (WithoutNap, WithNap, LongestNight, or LongestOnly) |
rawItems | NSArray<TSSleepDetailItem *> * | Array of raw sleep detail items from device/sync |
**Return Value**
| Type | Description |
|---|---|
NSArray<TSSleepDailyModel *> * | Array of processed daily sleep models sorted by sleep day, or nil if no input data |
**Code Example**
// Assuming rawSleepItems is obtained from previous sync
NSArray<TSSleepDetailItem *> *rawItems = /* obtained from sync */;
// Process using WithNap rule
NSArray<TSSleepDailyModel *> *dailyModels = [TSSleepDailyModel processWithStatisticsRule:TSSleepStatisticsRuleWithNap
rawItems:rawItems];
if (dailyModels) {
for (TSSleepDailyModel *model in dailyModels) {
TSLog(@"Night sleep segments: %lu", (unsigned long)model.nightSleeps.count);
TSLog(@"Daytime sleep segments: %lu", (unsigned long)model.daytimeSleeps.count);
TSLog(@"Valid naps: %lu", (unsigned long)model.validNaps.count);
}
}
Get Valid Daytime Naps
Filter daytime sleep segments by valid nap duration criteria.
- (NSArray<TSSleepSegment *> *)validNaps;
**Parameters**
None
**Return Value**
| Type | Description |
|---|---|
NSArray<TSSleepSegment *> * | Subset of daytime segments where duration is greater than 20 minutes and less than or equal to 3 hours; empty array if none match |
**Code Example**
TSSleepDailyModel *dailyModel = /* obtained from sync or processing */;
NSArray<TSSleepSegment *> *validNaps = [dailyModel validNaps];
if (validNaps.count > 0) {
for (TSSleepSegment *nap in validNaps) {
NSUInteger napDurationMinutes = nap.summary.totalSleepDuration / 60;
TSLog(@"Valid nap duration: %lu minutes", (unsigned long)napDurationMinutes);
}
}
Get Debug Description
Generate a human-readable multi-line description of daily sleep data for debugging.
- (NSString *)debugDescription;
**Parameters**
None
**Return Value**
| Type | Description |
|---|---|
NSString * | String summarizing date, rule, raw count, summary metrics, and segment counts |
**Code Example**
TSSleepDailyModel *dailyModel = /* obtained from sync or processing */;
TSLog(@"%@", [dailyModel debugDescription]);
Important Notes
-
**Sleep Day
Boundary**: Sleep data uses 20:00 (8 PM) as the day boundary instead of midnight. A sleep session starting at 21:00 on November 19 belongs to November 20, and a session at 08:00 on November 20 also belongs to November 20. The day boundary resets at 20:00 ([20:00→20:00) range). -
**Time Interval
Format**: All time parameters and return values use Unix timestamps in seconds (NSTimeInterval). Use[NSDate timeIntervalSince1970]for current time or[NSDate dateWithTimeIntervalSince1970:]for conversion. -
**Statistics
Rules**: Choose the appropriateTSSleepStatisticsRulebased on device capabilities. Different devices support different rules (WithoutNap, WithNap, LongestNight, or LongestOnly), affecting how naps and multiple sleep segments are processed. -
**Valid Nap
Duration**: A daytime sleep segment is considered a valid nap if its total sleep duration is greater than 20 minutes and less than or equal to 3 hours. Segments outside this range are still included indaytimeSleepsbut excluded fromvalidNaps. -
**REM Support
Verification**: Always checkisSupportREMSleepbefore assuming REM stage data is available. Not all devices support REM detection, andTSSleepDetailItemdata may not include REM stage segments if unsupported. -
**Raw vs Aggregated
Data**: UsesyncRawDataFromStartTime:completion:for fine-grained timeline analysis and custom calculations. UsesyncDailyDataFromStartTime:completion:for summary-level reporting and simplified access to daily statistics. -
**Segment
Classification**: Night sleep is determined by the statistics rule's time window (typically 20:00-09:00 or 20:00-12:00). Sleep sessions outside this window are classified as daytime sleep regardless of their actual clock time if nap support is enabled. -
**Data
Processing**: Raw items from sync may include awake segments and fragmented data. Use the processing methods to automatically group items by day, merge segments, and apply the selected statistics strategy. -
**Chronological
Order**: All returned arrays maintain chronological order for sleep items within segments and chronological ordering by sleep day for daily models, facilitating timeline visualization. -
**Null
Safety**: Completion callbacks may receive nil for the data parameter if an error occurs. Always check both the returned data and error parameters before processing results.