Blood Oxygen Module
The Blood Oxygen module provides comprehensive blood oxygen (SpO2) measurement and monitoring capabilities for wearable devices. It supports manual measurements initiated by users, automatic background monitoring with configurable schedules, and synchronization of raw and daily aggregated blood oxygen data. This module enables developers to integrate SpO2 vital sign tracking into their health and fitness applications.
Prerequisites
- Device must support blood oxygen measurement (verify with
isSupportActivityMeasureByUserandisSupportAutomaticMonitoring) - Proper Bluetooth connection to the wearable device must be established
- For automatic monitoring configuration, the device must support the feature (verify with
isSupportAutomaticMonitoring) - Time-based parameters use Unix timestamps (seconds since January 1, 1970)
Data Models
TSBOValueItem
Single blood oxygen measurement data point.
| Property | Type | Description |
|---|---|---|
oxyValue | UInt8 | Blood oxygen value as a percentage (0-100%). |
isUserInitiated | BOOL | Indicates whether the measurement was initiated by the user (YES) or automatically monitored (NO). |
TSBODailyModel
Daily aggregated blood oxygen data for a single day.
| Property | Type | Description |
|---|---|---|
maxOxygenItem | TSBOValueItem * | Reference to the TSBOValueItem with the highest SpO2 value recorded during the day. |
minOxygenItem | TSBOValueItem * | Reference to the TSBOValueItem with the lowest SpO2 value recorded during the day. |
manualItems | NSArray<TSBOValueItem *> * | Array of user-initiated blood oxygen measurements, sorted in ascending time order. |
autoItems | NSArray<TSBOValueItem *> * | Array of automatically monitored blood oxygen measurements, sorted in ascending time order. |
Enumerations
No enumerations are defined in this module.
Callback Types
TSCompletionBlock
typedef void (^TSCompletionBlock)(NSError *_Nullable error);
Generic completion callback for operations.
| Parameter | Type | Description |
|---|---|---|
error | NSError * | Error information if the operation failed; nil if successful. |
Measurement Start Handler
void(^)(BOOL success, NSError *_Nullable error)
Callback invoked when blood oxygen measurement starts or fails to start.
| Parameter | Type | Description |
|---|---|---|
success | BOOL | YES if measurement started successfully; NO otherwise. |
error | NSError * | Error details if the operation failed; nil if successful. |
Measurement Data Handler
void(^)(TSBOValueItem *_Nullable data, NSError *_Nullable error)
Callback invoked to receive real-time blood oxygen measurement data during an ongoing measurement.
| Parameter | Type | Description |
|---|---|---|
data | TSBOValueItem * | Real-time blood oxygen measurement data; nil if an error occurs. |
error | NSError * | Error information if data reception fails; nil if successful. |
Measurement End Handler
void(^)(BOOL success, NSError *_Nullable error)
Callback invoked when blood oxygen measurement ends, either normally or abnormally.
| Parameter | Type | Description |
|---|---|---|
success | BOOL | YES if measurement ended normally; NO if interrupted or failed. |
error | NSError * | Error details if the measurement ended abnormally; nil if normal end. |
Auto Monitor Config Fetch Handler
void (^)(TSAutoMonitorConfigs *_Nullable configuration, NSError *_Nullable error)
Callback for fetching automatic monitoring configuration.
| Parameter | Type | Description |
|---|---|---|
configuration | TSAutoMonitorConfigs * | Current automatic monitoring configuration; nil if an error occurs. |
error | NSError * | Error information if the fetch failed; nil if successful. |
Raw Data Sync Handler
void (^)(NSArray<TSBOValueItem *> *_Nullable boItems, NSError *_Nullable error)
Callback for raw blood oxygen data synchronization.
| Parameter | Type | Description |
|---|---|---|
boItems | NSArray<TSBOValueItem *> * | Array of raw blood oxygen measurement items synchronized; nil if an error occurs. |
error | NSError * | Error information if synchronization failed; nil if successful. |
Daily Data Sync Handler
void (^)(NSArray<TSBODailyModel *> *_Nullable dailyModels, NSError *_Nullable error)
Callback for daily aggregated blood oxygen data synchronization.
| Parameter | Type | Description |
|---|---|---|
dailyModels | NSArray<TSBODailyModel *> * | Array of daily blood oxygen models synchronized; nil if an error occurs. |
error | NSError * | Error information if synchronization failed; nil if successful. |
API Reference
Check manual blood oxygen measurement support
Determine whether the connected device supports user-initiated blood oxygen measurements.
- (BOOL)isSupportActivityMeasureByUser;
Returns: BOOL indicating device capability for manual measurement.
Code Example:
id<TSBloodOxygenInterface> boInterface = /* obtained from health manager */;
if ([boInterface isSupportActivityMeasureByUser]) {
TSLog(@"Device supports manual blood oxygen measurement");
} else {
TSLog(@"Device does not support manual blood oxygen measurement");
}
Start blood oxygen measurement
Begin a blood oxygen measurement session with real-time data streaming.
- (void)startMeasureWithParam:(TSActivityMeasureParam *_Nonnull)measureParam
startHandler:(void(^_Nullable)(BOOL success, NSError * _Nullable error))startHandler
dataHandler:(void(^_Nullable)(TSBOValueItem * _Nullable data, NSError * _Nullable error))dataHandler
endHandler:(void(^_Nullable)(BOOL success, NSError * _Nullable error))endHandler;
| Parameter | Type | Description |
|---|---|---|
measureParam | TSActivityMeasureParam * | Configuration parameters for the measurement activity. |
startHandler | void(^)(BOOL success, NSError *) | Callback invoked when measurement starts or fails to start. |
dataHandler | void(^)(TSBOValueItem *, NSError *) | Callback to receive real-time measurement data during the measurement. |
endHandler | void(^)(BOOL success, NSError *) | Callback invoked when the measurement ends or is interrupted. |
Code Example:
id<TSBloodOxygenInterface> boInterface = /* obtained from health manager */;
TSActivityMeasureParam *param = [[TSActivityMeasureParam alloc] init];
[boInterface startMeasureWithParam:param
startHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
TSLog(@"Blood oxygen measurement started successfully");
} else {
TSLog(@"Failed to start measurement: %@", error.localizedDescription);
}
}
dataHandler:^(TSBOValueItem * _Nullable data, NSError * _Nullable error) {
if (data) {
TSLog(@"Real-time SpO2: %d%%, User-initiated: %@",
data.oxyValue, data.isUserInitiated ? @"YES" : @"NO");
} else if (error) {
TSLog(@"Error receiving data: %@", error.localizedDescription);
}
}
endHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
TSLog(@"Measurement ended normally");
} else {
TSLog(@"Measurement interrupted: %@", error.localizedDescription);
}
}];
Stop blood oxygen measurement
Terminate the currently active blood oxygen measurement session.
- (void)stopMeasureCompletion:(nonnull TSCompletionBlock)completion;
| Parameter | Type | Description |
|---|---|---|
completion | TSCompletionBlock | Completion callback invoked when the measurement stops or fails to stop. |
Code Example:
id<TSBloodOxygenInterface> boInterface = /* obtained from health manager */;
[boInterface stopMeasureCompletion:^(NSError * _Nullable error) {
if (!error) {
TSLog(@"Blood oxygen measurement stopped successfully");
} else {
TSLog(@"Failed to stop measurement: %@", error.localizedDescription);
}
}];
Check automatic monitoring support
Determine whether the connected device supports automatic blood oxygen monitoring.
- (BOOL)isSupportAutomaticMonitoring;
Returns: BOOL indicating device capability for automatic monitoring.
Code Example:
id<TSBloodOxygenInterface> boInterface = /* obtained from health manager */;
if ([boInterface isSupportAutomaticMonitoring]) {
TSLog(@"Device supports automatic blood oxygen monitoring");
} else {
TSLog(@"Device does not support automatic blood oxygen monitoring");
}
Check monitor schedule time support
Determine whether the device supports configuring specific time ranges for automatic monitoring.
- (BOOL)isSupportMonitorScheduleTime;
Returns: BOOL indicating device support for time range configuration (startTime and endTime fields).
Code Example:
id<TSBloodOxygenInterface> boInterface = /* obtained from health manager */;
if ([boInterface isSupportMonitorScheduleTime]) {
TSLog(@"Device supports configuring monitor time range");
} else {
TSLog(@"Device does not support time range configuration");
}
Check monitor schedule interval support
Determine whether the device supports configuring the monitoring interval.
- (BOOL)isSupportMonitorScheduleInterval;
Returns: BOOL indicating device support for interval configuration.
Code Example:
id<TSBloodOxygenInterface> boInterface = /* obtained from health manager */;
if ([boInterface isSupportMonitorScheduleInterval]) {
TSLog(@"Device supports configuring monitor interval");
} else {
TSLog(@"Device does not support interval configuration");
}
Configure automatic blood oxygen monitoring
Push automatic monitoring configuration to the device.
- (void)pushAutoMonitorConfigs:(TSAutoMonitorConfigs *_Nonnull)configuration
completion:(nonnull TSCompletionBlock)completion;
| Parameter | Type | Description |
|---|---|---|
configuration | TSAutoMonitorConfigs * | Automatic monitoring configuration parameters (enable/disable, schedule, interval). |
completion | TSCompletionBlock | Completion callback invoked when the configuration is applied or fails. |
Code Example:
id<TSBloodOxygenInterface> boInterface = /* obtained from health manager */;
TSAutoMonitorConfigs *config = [[TSAutoMonitorConfigs alloc] init];
config.isEnabled = YES;
// Configure additional properties as needed
[boInterface pushAutoMonitorConfigs:config
completion:^(NSError * _Nullable error) {
if (!error) {
TSLog(@"Automatic monitoring configuration applied successfully");
} else {
TSLog(@"Failed to apply configuration: %@", error.localizedDescription);
}
}];
Fetch current automatic monitoring configuration
Retrieve the current automatic blood oxygen monitoring settings from the device.
- (void)fetchAutoMonitorConfigsWithCompletion:(nonnull void (^)(TSAutoMonitorConfigs *_Nullable configuration, NSError *_Nullable error))completion;
| Parameter | Type | Description |
|---|---|---|
completion | void(^)(TSAutoMonitorConfigs *, NSError *) | Callback returning current configuration or error. |
Code Example:
id<TSBloodOxygenInterface> boInterface = /* obtained from health manager */;
[boInterface fetchAutoMonitorConfigsWithCompletion:^(TSAutoMonitorConfigs * _Nullable configuration, NSError * _Nullable error) {
if (configuration) {
TSLog(@"Current monitoring config - Enabled: %@",
configuration.isEnabled ? @"YES" : @"NO");
} else if (error) {
TSLog(@"Failed to fetch configuration: %@", error.localizedDescription);
}
}];
Synchronize raw blood oxygen data (time range)
Retrieve all raw blood oxygen measurement data points within a specified time range.
- (void)syncRawDataFromStartTime:(NSTimeInterval)startTime
endTime:(NSTimeInterval)endTime
completion:(nonnull void (^)(NSArray<TSBOValueItem *> *_Nullable boItems, NSError *_Nullable error))completion;
| Parameter | Type | Description |
|---|---|---|
startTime | NSTimeInterval | Start time (Unix timestamp in seconds) for data retrieval. |
endTime | NSTimeInterval | End time (Unix timestamp in seconds) for data retrieval. |
completion | void(^)(NSArray<TSBOValueItem *> *, NSError *) | Callback with raw blood oxygen items or error. |
Code Example:
id<TSBloodOxygenInterface> boInterface = /* obtained from health manager */;
NSDate *startDate = [NSDate dateWithTimeIntervalSinceNow:-86400]; // 24 hours ago
NSDate *endDate = [NSDate date];
[boInterface syncRawDataFromStartTime:startDate.timeIntervalSince1970
endTime:endDate.timeIntervalSince1970
completion:^(NSArray<TSBOValueItem *> * _Nullable boItems, NSError * _Nullable error) {
if (boItems) {
TSLog(@"Synchronized %lu raw blood oxygen measurements", (unsigned long)boItems.count);
for (TSBOValueItem *item in boItems) {
TSLog(@"SpO2: %d%% at %f, User-initiated: %@",
item.oxyValue, item.timestamp, item.isUserInitiated ? @"YES" : @"NO");
}
} else if (error) {
TSLog(@"Failed to sync raw data: %@", error.localizedDescription);
}
}];
Synchronize raw blood oxygen data (from start time)
Retrieve all raw blood oxygen measurement data points from a specified start time until now.
- (void)syncRawDataFromStartTime:(NSTimeInterval)startTime
completion:(nonnull void (^)(NSArray<TSBOValueItem *> *_Nullable boItems, NSError *_Nullable error))completion;
| Parameter | Type | Description |
|---|---|---|
startTime | NSTimeInterval | Start time (Unix timestamp in seconds) for data retrieval. Synchronizes from this time to the current time. |
completion | void(^)(NSArray<TSBOValueItem *> *, NSError *) | Callback with raw blood oxygen items or error. |
Code Example:
id<TSBloodOxygenInterface> boInterface = /* obtained from health manager */;
NSDate *startDate = [NSDate dateWithTimeIntervalSinceNow:-604800]; // 7 days ago
[boInterface syncRawDataFromStartTime:startDate.timeIntervalSince1970
completion:^(NSArray<TSBOValueItem *> * _Nullable boItems, NSError * _Nullable error) {
if (boItems) {
TSLog(@"Synchronized %lu raw blood oxygen measurements from 7 days ago",
(unsigned long)boItems.count);
} else if (error) {
TSLog(@"Failed to sync raw data: %@", error.localizedDescription);
}
}];
Synchronize daily blood oxygen data (time range)
Retrieve daily aggregated blood oxygen data within a specified time range.
- (void)syncDailyDataFromStartTime:(NSTimeInterval)startTime
endTime:(NSTimeInterval)endTime
completion:(nonnull void (^)(NSArray<TSBODailyModel *> *_Nullable dailyModels, NSError *_Nullable error))completion;
| Parameter | Type | Description |
|---|---|---|
startTime | NSTimeInterval | Start time (Unix timestamp in seconds). Automatically normalized to 00:00:00 of the specified day. |
endTime | NSTimeInterval | End time (Unix timestamp in seconds). Automatically normalized to 23:59:59 of the specified day. Must be after startTime and not in the future. |
completion | void(^)(NSArray<TSBODailyModel *> *, NSError *) | Callback with daily aggregated blood oxygen models or error. |
Code Example:
id<TSBloodOxygenInterface> boInterface = /* obtained from health manager */;
NSDate *startDate = [NSDate dateWithTimeIntervalSinceNow:-604800]; // 7 days ago
NSDate *endDate = [NSDate date];
[boInterface syncDailyDataFromStartTime:startDate.timeIntervalSince1970
endTime:endDate.timeIntervalSince1970
completion:^(NSArray<TSBODailyModel *> * _Nullable dailyModels, NSError * _Nullable error) {
if (dailyModels) {
TSLog(@"Synchronized %lu days of blood oxygen data", (unsigned long)dailyModels.count);
for (TSBODailyModel *daily in dailyModels) {
TSLog(@"Day - Max: %d%%, Min: %d%%, Manual: %lu, Auto: %lu",
[daily maxOxygenValue], [daily minOxygenValue],
(unsigned long)daily.manualItems.count,
(unsigned long)daily.autoItems.count);
}
} else if (error) {
TSLog(@"Failed to sync daily data: %@", error.localizedDescription);
}
}];
Synchronize daily blood oxygen data (from start time)
Retrieve daily aggregated blood oxygen data from a specified start time until now.
- (void)syncDailyDataFromStartTime:(NSTimeInterval)startTime
completion:(nonnull void (^)(NSArray<TSBODailyModel *> *_Nullable dailyModels, NSError *_Nullable error))completion;
| Parameter | Type | Description |
|---|---|---|
startTime | NSTimeInterval | Start time (Unix timestamp in seconds). Automatically normalized to 00:00:00 of the specified day. Synchronizes from this time to the current time. |
completion | void(^)(NSArray<TSBODailyModel *> *, NSError *) | Callback with daily aggregated blood oxygen models or error. |
Code Example:
id<TSBloodOxygenInterface> boInterface = /* obtained from health manager */;
NSDate *startDate = [NSDate dateWithTimeIntervalSinceNow:-2592000]; // 30 days ago
[boInterface syncDailyDataFromStartTime:startDate.timeIntervalSince1970
completion:^(NSArray<TSBODailyModel *> * _Nullable dailyModels, NSError * _Nullable error) {
if (dailyModels) {
TSLog(@"Synchronized %lu days of daily blood oxygen aggregates",
(unsigned long)dailyModels.count);
for (TSBODailyModel *daily in dailyModels) {
NSArray<TSBOValueItem *> *allItems = [daily allMeasuredItems];
TSLog(@"Day aggregate - Total samples: %lu, Max: %d%%, Min: %d%%",
(unsigned long)allItems.count,
[daily maxOxygenValue],
[daily minOxygenValue]);
}
} else if (error) {
TSLog(@"Failed to sync daily data: %@", error.localizedDescription);
}
}];
Important Notes
-
**Device Capability
Verification**: Always verify device capabilities using theisSupportXXXmethods before attempting to use features. Not all devices support manual measurement, automatic monitoring, or schedule configuration. -
**Time
Parameters**: All time-based API parameters use Unix timestamps (seconds since January 1, 1970). UseNSDate.timeIntervalSince1970to convert dates to timestamps. -
**Daily Data
Normalization**: When calling daily data synchronization methods, time parameters are automatically normalized to day boundaries (00:00:00 to 23:59:59). ThestartTimemust be earlier thanendTime, andendTimemust not be in the future. -
**Real-time Data
Streaming**: The data handler callback during measurement may be called multiple times with updated real-time measurements. Ensure the handler is thread-safe and does not block the main thread. -
**Measurement Session
Management**: Only one active measurement session can run at a time. CallstopMeasurebefore starting a new measurement to ensure proper resource cleanup. -
**Automatic Monitoring
Schedule**: UseisSupportMonitorScheduleTimeandisSupportMonitorScheduleIntervalto determine which schedule fields are supported before configuring automatic monitoring. -
**Data
Ordering**: All data arrays are sorted in ascending time order (oldest to newest). Manual and auto items are maintained separately in daily models; useallMeasuredItemsto retrieve a combined, time-sorted array. -
**Callback
Thread**: Completion handlers are called on the main thread. Avoid performing long-running operations directly in callbacks. -
**Error
Handling**: Always check both the return values and error parameters in callbacks. Anildata/model combined with a non-nil error indicates a failure. -
**SpO2 Value
Range**: Blood oxygen values are represented asUInt8percentages (0–100%). Values outside the typical physiological range (typically 94–100% for healthy individuals at sea level) may indicate measurement issues or health concerns.