睡眠(TSSleep)
TSSleep 模块提供设备睡眠数据的同步和处理功能,包括夜间睡眠、日间小睡等详细的睡眠阶段分析。支持多种统计规则以适配不同设备的能力和场景需求。
前提条件
- SDK 已正确初始化并连接到设备
- 设备支持睡眠数据采集功能
- 用户已授予应用访问睡眠数据的权限
- 根据设备支持情况,了解相应的统计规则和数据格式
数据模型
TSSleepDetailItem - 睡眠明细条目
| 属性名 | 类型 | 说明 |
|---|---|---|
stage | TSSleepStage | 睡眠阶段类型(清醒/浅睡/深睡/REM) |
belongingDate | NSTimeInterval | 所属日期时间戳(0时0分0秒)。睡眠以 20:00 为跨天分隔线 |
TSSleepSummary - 睡眠汇总统计
| 属性名 | 类型 | 说明 |
|---|---|---|
startTime | NSTimeInterval | 睡眠开始时间(Unix 时间戳) |
endTime | NSTimeInterval | 睡眠结束时间(Unix 时间戳) |
duration | NSTimeInterval | 总持续时间(秒)= endTime - startTime |
totalSleepDuration | NSTimeInterval | 总睡眠时长(秒),不包括清醒时间 |
qualityScore | UInt8 | 睡眠质量评分(0-100) |
awakeDuration | NSTimeInterval | 睡眠期间清醒时长(秒) |
lightSleepDuration | NSTimeInterval | 浅睡总时长(秒) |
deepSleepDuration | NSTimeInterval | 深睡总时长(秒) |
remDuration | NSTimeInterval | REM 睡眠总时长(秒) |
awakePercentage | UInt8 | 清醒时间百分比 |
lightSleepPercentage | UInt8 | 浅睡时间百分比 |
deepSleepPercentage | UInt8 | 深睡时间百分比 |
remPercentage | UInt8 | REM 时间百分比 |
awakeCount | UInt16 | 觉醒次数 |
lightSleepCount | UInt16 | 浅睡次数 |
deepSleepCount | UInt16 | 深睡次数 |
remCount | UInt16 | REM 次数 |
TSSleepSegment - 睡眠段
| 属性名 | 类型 | 说明 |
|---|---|---|
periodType | TSSleepPeriodType | 睡眠时段类型(夜间/日间) |
summary | TSSleepSummary * | 该睡眠段的统计汇总 |
detailItems | NSArray<TSSleepDetailItem *> * | 按时间顺序的睡眠阶段详情条目 |
TSSleepDailyModel - 每日睡眠数据模型
| 属性名 | 类型 | 说明 |
|---|---|---|
statisticsRule | TSSleepStatisticsRule | 此睡眠记录使用的统计规则 |
dailySummary | TSSleepSummary * | 当日睡眠总体汇总 |
rawSleepItems | NSArray<TSSleepDetailItem *> * | 原始睡眠数据条目数组(未经处理) |
nightSleeps | NSArray<TSSleepSegment *> * | 夜间睡眠段数组 |
daytimeSleeps | NSArray<TSSleepSegment *> * | 日间睡眠段数组(全部片段) |
枚举与常量
TSSleepStage - 睡眠阶段类型
| 值 | 枚举名 | 说明 |
|---|---|---|
| 0 | TSSleepStageAwake | 清醒阶段 |
| 1 | TSSleepStageLight | 浅睡阶段(N1 & N2) |
| 2 | TSSleepStageDeep | 深睡阶段(N3,慢波睡眠) |
| 3 | TSSleepStageREM | 快速眼动睡眠阶段(做梦阶段) |
TSSleepStatisticsRule - 睡眠统计规则类型
| 值 | 枚举名 | 说明 |
|---|---|---|
| 0 | TSSleepStatisticsRuleWithoutNap | 基础规则:不带小睡功能,传感器 20:00-12:00 激活,所有睡眠视为夜间睡眠 |
| 1 | TSSleepStatisticsRuleWithNap | 带小睡功能:传感器 24 小时激活,区分夜间和日间睡眠 |
| 2 | TSSleepStatisticsRuleLongestNight | 最长夜间段:使用最长连续夜间睡眠段(20:00-08:00),有效小睡计入统计 |
| 3 | TSSleepStatisticsRuleLongestOnly | 仅最长段:不区分夜间日间,仅使用最长连续睡眠段 |
TSSleepPeriodType - 睡眠时段类型
| 值 | 枚举名 | 说明 |
|---|---|---|
| 0 | TSSleepPeriodTypeNight | 夜间睡眠(20:00-09:00) |
| 1 | TSSleepPeriodTypeDaytime | 日间睡眠(09:00-20:00) |
接口方法
检查 REM 睡眠支持
- (BOOL)isSupportREMSleep;
| 参数 | 类型 | 说明 |
|---|---|---|
| 返回值 | BOOL | 如果设备支持识别并记录 REM 睡眠阶段返回 YES,否则返回 NO |
说明
REM 睡眠是以快速眼球运动和生动梦境为特征的独特睡眠阶段,在记忆巩固和情绪处理中起关键作用。当返回 YES 时,TSSleepDetailItem 数据中可能包含 REM 阶段分段。
代码示例
id<TSSleepInterface> sleepInterface = // 获取睡眠接口
BOOL supportREM = [sleepInterface isSupportREMSleep];
if (supportREM) {
TSLog(@"设备支持 REM 睡眠识别");
} else {
TSLog(@"设备不支持 REM 睡眠识别");
}
从指定开始时间同步原始睡眠分段数据
- (void)syncRawDataFromStartTime:(NSTimeInterval)startTime
completion:(nonnull void (^)(NSArray<TSSleepDetailItem *> *_Nullable sleepItems, NSError *_Nullable error))completion;
| 参数 | 类型 | 说明 |
|---|---|---|
startTime | NSTimeInterval | 起始时间的 Unix 时间戳(秒) |
completion | void (^)(NSArray<TSSleepDetailItem *> *_Nullable, NSError *_Nullable) | 回调,返回 TSSleepDetailItem 数组或错误信息 |
说明
返回原始睡眠分段(开始/结束/时长/阶段/时段),适合做细粒度时间线与自定义分析。
代码示例
id<TSSleepInterface> sleepInterface = // 获取睡眠接口
// 获取 7 天前的睡眠数据
NSTimeInterval startTime = [[NSDate dateWithTimeIntervalSinceNow:-7*24*3600] timeIntervalSince1970];
[sleepInterface syncRawDataFromStartTime:startTime completion:^(NSArray<TSSleepDetailItem *> *_Nullable sleepItems, NSError *_Nullable error) {
if (error) {
TSLog(@"获取睡眠数据失败: %@", error.localizedDescription);
return;
}
for (TSSleepDetailItem *item in sleepItems) {
TSLog(@"睡眠阶段: %ld, 时间: %.0f", (long)item.stage, item.timestamp);
}
}];
在指定时间区间内同步原始睡眠分段数据
- (void)syncRawDataFromStartTime:(NSTimeInterval)startTime
endTime:(NSTimeInterval)endTime
completion:(nonnull void (^)(NSArray<TSSleepDetailItem *> *_Nullable sleepItems, NSError *_Nullable error))completion;
| 参数 | 类型 | 说明 |
|---|---|---|
startTime | NSTimeInterval | 区间开始时间的 Unix 时间戳(秒,含) |
endTime | NSTimeInterval | 区间结束时间的 Unix 时间戳(秒,不含)。时间区间为 [startTime, endTime) |
completion | void (^)(NSArray<TSSleepDetailItem *> *_Nullable, NSError *_Nullable) | 回调,返回 TSSleepDetailItem 数组或错误信息 |
说明
适用于限定时间窗口获取原始分段数据的场景。
代码示例
id<TSSleepInterface> sleepInterface = // 获取睡眠接口
// 获取最近 7 天的睡眠数据
NSTimeInterval endTime = [[NSDate date] timeIntervalSince1970];
NSTimeInterval startTime = endTime - 7*24*3600;
[sleepInterface syncRawDataFromStartTime:startTime endTime:endTime completion:^(NSArray<TSSleepDetailItem *> *_Nullable sleepItems, NSError *_Nullable error) {
if (error) {
TSLog(@"获取睡眠数据失败: %@", error.localizedDescription);
return;
}
TSLog(@"获取到 %lu 条睡眠数据", (unsigned long)sleepItems.count);
// 统计各阶段时长
NSTimeInterval lightDuration = 0, deepDuration = 0, remDuration = 0, awakeDuration = 0;
for (TSSleepDetailItem *item in sleepItems) {
switch (item.stage) {
case TSSleepStageLight:
lightDuration += item.duration;
break;
case TSSleepStageDeep:
deepDuration += item.duration;
break;
case TSSleepStageREM:
remDuration += item.duration;
break;
case TSSleepStageAwake:
awakeDuration += item.duration;
break;
}
}
TSLog(@"浅睡: %.0f秒, 深睡: %.0f秒, REM: %.0f秒, 清醒: %.0f秒",
lightDuration, deepDuration, remDuration, awakeDuration);
}];
从指定开始时间同步按天聚合的睡眠数据
- (void)syncDailyDataFromStartTime:(NSTimeInterval)startTime
completion:(nonnull void (^)(NSArray<TSSleepDailyModel *> *_Nullable sleepModel, NSError *_Nullable error))completion;
| 参数 | 类型 | 说明 |
|---|---|---|
startTime | NSTimeInterval | 起始"自然日"的 Unix 时间戳(秒) |
completion | void (^)(NSArray<TSSleepDailyModel *> *_Nullable, NSError *_Nullable) | 回调,返回按天聚合的 TSSleepDailyModel 数组或错误信息 |
说明
返回每日睡眠汇总(总时长、结构构成、质量指标等)。
代码示例
id<TSSleepInterface> sleepInterface = // 获取睡眠接口
// 获取最近 30 天的每日睡眠数据
NSTimeInterval startTime = [[NSDate dateWithTimeIntervalSinceNow:-30*24*3600] timeIntervalSince1970];
[sleepInterface syncDailyDataFromStartTime:startTime completion:^(NSArray<TSSleepDailyModel *> *_Nullable sleepModels, NSError *_Nullable error) {
if (error) {
TSLog(@"获取每日睡眠数据失败: %@", error.localizedDescription);
return;
}
for (TSSleepDailyModel *model in sleepModels) {
TSSleepSummary *summary = model.dailySummary;
TSLog(@"日期: %@, 睡眠时长: %.1f小时, 质量评分: %d",
[NSDate dateWithTimeIntervalSince1970:model.startTime],
summary.totalSleepDuration / 3600.0,
summary.qualityScore);
TSLog(@" 浅睡: %.1f小时 (%d%%), 深睡: %.1f小时 (%d%%), REM: %.1f小时 (%d%%)",
summary.lightSleepDuration / 3600.0, summary.lightSleepPercentage,
summary.deepSleepDuration / 3600.0, summary.deepSleepPercentage,
summary.remDuration / 3600.0, summary.remPercentage);
TSLog(@" 夜间睡眠段: %lu, 日间小睡: %lu",
(unsigned long)model.nightSleeps.count,
(unsigned long)model.daytimeSleeps.count);
}
}];
在指定时间区间内同步按天聚合的睡眠数据
- (void)syncDailyDataFromStartTime:(NSTimeInterval)startTime
endTime:(NSTimeInterval)endTime
completion:(nonnull void (^)(NSArray<TSSleepDailyModel *> *_Nullable sleepModel, NSError *_Nullable error))completion;
| 参数 | 类型 | 说明 |
|---|---|---|
startTime | NSTimeInterval | 区间起始"自然日"的 Unix 时间戳(秒,含) |
endTime | NSTimeInterval | 区间结束"自然日"的 Unix 时间戳(秒,不含)。日期区间为 [startTime, endTime) |
completion | void (^)(NSArray<TSSleepDailyModel *> *_Nullable, NSError *_Nullable) | 回调,返回按天聚合的 TSSleepDailyModel 数组或错误信息 |
说明
适用于限定日期范围获取按天汇总数据。
代码示例
id<TSSleepInterface> sleepInterface = // 获取睡眠接口
// 获取特定时间段(2025-01-01 至 2025-01-31)的每日睡眠数据
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd";
NSDate *startDate = [formatter dateFromString:@"2025-01-01"];
NSDate *endDate = [formatter dateFromString:@"2025-02-01"];
NSTimeInterval startTime = [startDate timeIntervalSince1970];
NSTimeInterval endTime = [endDate timeIntervalSince1970];
[sleepInterface syncDailyDataFromStartTime:startTime endTime:endTime completion:^(NSArray<TSSleepDailyModel *> *_Nullable sleepModels, NSError *_Nullable error) {
if (error) {
TSLog(@"获取每日睡眠数据失败: %@", error.localizedDescription);
return;
}
// 计算平均睡眠时长和平均质量评分
NSTimeInterval totalSleep = 0;
UInt32 totalScore = 0;
for (TSSleepDailyModel *model in sleepModels) {
totalSleep += model.dailySummary.totalSleepDuration;
totalScore += model.dailySummary.qualityScore;
}
if (sleepModels.count > 0) {
TSLog(@"本月平均睡眠时长: %.1f小时", totalSleep / 3600.0 / sleepModels.count);
TSLog(@"本月平均睡眠质量评分: %d", totalScore / (UInt32)sleepModels.count);
}
}];
静态处理方法
处理原始睡眠数据
+ (nullable NSArray<TSSleepDailyModel *> *)processWithStatisticsRule:(TSSleepStatisticsRule)statisticsRule
rawItems:(NSArray<TSSleepDetailItem *> *)rawItems;
| 参数 | 类型 | 说明 |
|---|---|---|
statisticsRule | TSSleepStatisticsRule | 统计规则选择器(如不带小睡、带小睡、最长夜间段、仅最长段等) |
rawItems | NSArray<TSSleepDetailItem *> * | 设备或同步侧的原始睡眠明细条目;为空或 nil 时处理器返回 nil |
| 返回值 | NSArray<TSSleepDailyModel *> * | 按睡眠日排序的 TSSleepDailyModel 数组;无原始数据时为 nil |
说明
对 TSSleepDataProcessor 的便捷封装:按归属日分组、整理清醒段并执行对应策略。
代码示例
// 假设已通过 syncRawDataFromStartTime:endTime:completion: 获得原始睡眠数据
NSArray<TSSleepDetailItem *> *rawItems = // 原始睡眠数据
// 使用"带小睡功能"规则处理数据
NSArray<TSSleepDailyModel *> *dailyModels = [TSSleepDailyModel processWithStatisticsRule:TSSleepStatisticsRuleWithNap rawItems:rawItems];
if (dailyModels) {
for (TSSleepDailyModel *model in dailyModels) {
TSLog(@"统计规则: %ld", (long)model.statisticsRule);
TSLog(@"夜间睡眠段数: %lu", (unsigned long)model.nightSleeps.count);
TSLog(@"日间睡眠段数: %lu", (unsigned long)model.daytimeSleeps.count);
// 检查有效小睡
NSArray<TSSleepSegment *> *validNaps = [model validNaps];
TSLog(@"有效小睡数: %lu (20分钟 < 时长 <= 3小时)", (unsigned long)validNaps.count);
}
}
获取有效日间小睡
- (NSArray<TSSleepSegment *> *)validNaps;
| 返回值 | 类型 | 说明 |
|---|---|---|
| 返回值 | NSArray<TSSleepSegment *> * | 满足时长规则的日间片段数组;无匹配时为空数组 |
说明
按分段汇总中的实际睡眠总时长筛选:大于 20 分钟且小于等于 3 小时;不依赖分段上的 isValid 字段。
代码示例
TSSleepDailyModel *sleepModel = // 获取睡眠模型
// 获取有效小睡(20分钟 < 时长 <= 3小时)
NSArray<TSSleepSegment *> *validNaps = [sleepModel validNaps];
TSLog(@"今天有效小睡次数: %lu", (unsigned long)validNaps.count);
for (TSSleepSegment *nap in validNaps) {
NSTimeInterval napDuration = nap.summary.totalSleepDuration;
TSLog(@"小睡时长: %.0f分钟", napDuration / 60.0);
}
注意事项
-
时间戳格式:所有时间参数均为 Unix 时间戳(秒),需转换为
NSTimeInterval格式 -
睡眠日期计算:睡眠数据以 20:00 为跨天分隔线 [20:00→20:00)。例如:
- 2025-11-19 21:00 的睡眠归属于 2025-11-20
- 2025-11-20 08:00 的睡眠归属于 2025-11-20
- 2025-11-20 21:00 的睡眠归属于 2025-11-21
-
统计规则差异:不同设备支持不同的统计规则,请根据设备能力选择合适的规则:
WithoutNap:不带小睡功能,传感器 20:00-12:00 激活WithNap:带小睡功能,传感器 24 小时激活LongestNight:使用最长夜间睡眠段,夜间窗口 20:00-08:00LongestOnly:不区分夜间和日间,仅使用最长连续睡眠
-
回调线程:数据同步回调可能在后台线程执行,更新 UI 时需回到主线程
-
REM 睡眠支持:使用前应先调用
isSupportREMSleep检查设备是否支持 REM 睡眠阶段识别 -
数据时间范围:时间范围的结束时间不含(半开区间 [startTime, endTime)),设计查询时应注意边界值
-
有效小睡标准:有效小睡时长规则为 20 分钟 < 时长 ≤ 3 小时,可通过
validNaps方法便捷获取 -
原始数据处理:原始睡眠数据包含清醒阶段,处理时应考虑清醒段对睡眠结构的影响