跳到主要内容

睡眠(TSSleep)

TSSleep 模块提供设备睡眠数据的同步和处理功能,包括夜间睡眠、日间小睡等详细的睡眠阶段分析。支持多种统计规则以适配不同设备的能力和场景需求。

前提条件

  1. SDK 已正确初始化并连接到设备
  2. 设备支持睡眠数据采集功能
  3. 用户已授予应用访问睡眠数据的权限
  4. 根据设备支持情况,了解相应的统计规则和数据格式

数据模型

TSSleepDetailItem - 睡眠明细条目

属性名类型说明
stageTSSleepStage睡眠阶段类型(清醒/浅睡/深睡/REM)
belongingDateNSTimeInterval所属日期时间戳(0时0分0秒)。睡眠以 20:00 为跨天分隔线

TSSleepSummary - 睡眠汇总统计

属性名类型说明
startTimeNSTimeInterval睡眠开始时间(Unix 时间戳)
endTimeNSTimeInterval睡眠结束时间(Unix 时间戳)
durationNSTimeInterval总持续时间(秒)= endTime - startTime
totalSleepDurationNSTimeInterval总睡眠时长(秒),不包括清醒时间
qualityScoreUInt8睡眠质量评分(0-100)
awakeDurationNSTimeInterval睡眠期间清醒时长(秒)
lightSleepDurationNSTimeInterval浅睡总时长(秒)
deepSleepDurationNSTimeInterval深睡总时长(秒)
remDurationNSTimeIntervalREM 睡眠总时长(秒)
awakePercentageUInt8清醒时间百分比
lightSleepPercentageUInt8浅睡时间百分比
deepSleepPercentageUInt8深睡时间百分比
remPercentageUInt8REM 时间百分比
awakeCountUInt16觉醒次数
lightSleepCountUInt16浅睡次数
deepSleepCountUInt16深睡次数
remCountUInt16REM 次数

TSSleepSegment - 睡眠段

属性名类型说明
periodTypeTSSleepPeriodType睡眠时段类型(夜间/日间)
summaryTSSleepSummary *该睡眠段的统计汇总
detailItemsNSArray<TSSleepDetailItem *> *按时间顺序的睡眠阶段详情条目

TSSleepDailyModel - 每日睡眠数据模型

属性名类型说明
statisticsRuleTSSleepStatisticsRule此睡眠记录使用的统计规则
dailySummaryTSSleepSummary *当日睡眠总体汇总
rawSleepItemsNSArray<TSSleepDetailItem *> *原始睡眠数据条目数组(未经处理)
nightSleepsNSArray<TSSleepSegment *> *夜间睡眠段数组
daytimeSleepsNSArray<TSSleepSegment *> *日间睡眠段数组(全部片段)

枚举与常量

TSSleepStage - 睡眠阶段类型

枚举名说明
0TSSleepStageAwake清醒阶段
1TSSleepStageLight浅睡阶段(N1 & N2)
2TSSleepStageDeep深睡阶段(N3,慢波睡眠)
3TSSleepStageREM快速眼动睡眠阶段(做梦阶段)

TSSleepStatisticsRule - 睡眠统计规则类型

枚举名说明
0TSSleepStatisticsRuleWithoutNap基础规则:不带小睡功能,传感器 20:00-12:00 激活,所有睡眠视为夜间睡眠
1TSSleepStatisticsRuleWithNap带小睡功能:传感器 24 小时激活,区分夜间和日间睡眠
2TSSleepStatisticsRuleLongestNight最长夜间段:使用最长连续夜间睡眠段(20:00-08:00),有效小睡计入统计
3TSSleepStatisticsRuleLongestOnly仅最长段:不区分夜间日间,仅使用最长连续睡眠段

TSSleepPeriodType - 睡眠时段类型

枚举名说明
0TSSleepPeriodTypeNight夜间睡眠(20:00-09:00)
1TSSleepPeriodTypeDaytime日间睡眠(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;
参数类型说明
startTimeNSTimeInterval起始时间的 Unix 时间戳(秒)
completionvoid (^)(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;
参数类型说明
startTimeNSTimeInterval区间开始时间的 Unix 时间戳(秒,含)
endTimeNSTimeInterval区间结束时间的 Unix 时间戳(秒,不含)。时间区间为 [startTime, endTime)
completionvoid (^)(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;
参数类型说明
startTimeNSTimeInterval起始"自然日"的 Unix 时间戳(秒)
completionvoid (^)(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;
参数类型说明
startTimeNSTimeInterval区间起始"自然日"的 Unix 时间戳(秒,含)
endTimeNSTimeInterval区间结束"自然日"的 Unix 时间戳(秒,不含)。日期区间为 [startTime, endTime)
completionvoid (^)(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;
参数类型说明
statisticsRuleTSSleepStatisticsRule统计规则选择器(如不带小睡、带小睡、最长夜间段、仅最长段等)
rawItemsNSArray<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);
}

注意事项

  1. 时间戳格式:所有时间参数均为 Unix 时间戳(秒),需转换为 NSTimeInterval 格式

  2. 睡眠日期计算:睡眠数据以 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
  3. 统计规则差异:不同设备支持不同的统计规则,请根据设备能力选择合适的规则:

    • WithoutNap:不带小睡功能,传感器 20:00-12:00 激活
    • WithNap:带小睡功能,传感器 24 小时激活
    • LongestNight:使用最长夜间睡眠段,夜间窗口 20:00-08:00
    • LongestOnly:不区分夜间和日间,仅使用最长连续睡眠
  4. 回调线程:数据同步回调可能在后台线程执行,更新 UI 时需回到主线程

  5. REM 睡眠支持:使用前应先调用 isSupportREMSleep 检查设备是否支持 REM 睡眠阶段识别

  6. 数据时间范围:时间范围的结束时间不含(半开区间 [startTime, endTime)),设计查询时应注意边界值

  7. 有效小睡标准:有效小睡时长规则为 20 分钟 < 时长 ≤ 3 小时,可通过 validNaps 方法便捷获取

  8. 原始数据处理:原始睡眠数据包含清醒阶段,处理时应考虑清醒段对睡眠结构的影响