Data Synchronization (TSDataSync)
TSDataSync synchronizes daily aggregated and raw health data. Each requested data type reports through a per-type callback, and the final completion returns the aggregate results.
Prerequisites
- The device is connected and authenticated.
- The SDK has been initialized.
startTimeis earlier thanendTime;endTimemust not be in the future.- Check
isSyncingbefore starting another operation.
Data models
TSDataSyncConfig
| Property | Type | Description |
|---|---|---|
options | TSDataSyncOption | Data types to synchronize; combine flags with bitwise OR |
granularity | TSDataGranularity | Raw or daily aggregated data |
startTime | NSTimeInterval | Unix seconds; 0 reads the last sync time from the database |
endTime | NSTimeInterval | Unix seconds; 0 uses the current time |
includeUserInitiated | BOOL | Include user-initiated measurements; defaults to YES |
Initializers are init, initWithOptions:granularity:, and initWithOptions:granularity:startTime:endTime:. Convenience constructors are configForRawDataWithOptions:startTime:endTime:, configForDailyDataWithOptions:startTime:endTime:, and configWithOptions:granularity:startTime:.
TSHealthData
| Property | Type | Description |
|---|---|---|
option | TSDataSyncOption | Data type represented by this result |
healthValues | NSArray<TSHealthValueModel *> * | Values in ascending time order; empty when no data exists |
fetchError | NSError * | Error for this data type; nil on success, including an empty result |
Create TSHealthData with initWithOption:healthValues:fetchError: or its class methods. Use findHealthDataWithOption:fromArray: to locate one type in the final result array.
TSHealthValueType
Value kinds are TSHealthValueTypeNormal (0), TSHealthValueTypeMax (1), TSHealthValueTypeMin (2), and TSHealthValueTypeResting (3). Resting values apply only to heart-rate data.
Enumerations and options
TSDataGranularity
| Value | Description |
|---|---|
TSDataGranularityRaw (0) | Individual measurements |
TSDataGranularityDay (1) | Daily aggregated data |
TSDataSyncOption
TSDataSyncOptionNone is 0. The remaining flags are HeartRate, BloodOxygen, BloodPressure, Stress, Sleep, Temperature, ECG, Sport, DailyActivity, and HeartRateVar. Combine them with bitwise OR. TSDataSyncOptionAll combines every flag.
Callback types
TSDataSyncHealthDataBlock is void (^)(TSHealthData *typeData). It is called once on the main thread when each capability-filtered data type finishes. Per-type failures are reported by typeData.fetchError. Resting heart-rate values are included in the heart-rate result and are identified by valueType == TSHealthValueTypeResting on the value item.
The final completion has this signature:
void (^)(NSArray<TSHealthData *> *_Nullable results, NSError *_Nullable error)
error is reserved for fatal errors that stop synchronization. A data-type failure is reported in that type's TSHealthData.fetchError.
API reference
Synchronize daily data from the last sync time
- (void)syncDailyDataFromLastTime:(nullable TSDataSyncHealthDataBlock)onHealthData
completion:(void (^)(NSArray<TSHealthData *> *_Nullable results,
NSError *_Nullable error))completion;
Synchronize raw data from the last sync time
- (void)syncRawDataFromLastTime:(nullable TSDataSyncHealthDataBlock)onHealthData
completion:(void (^)(NSArray<TSHealthData *> *_Nullable results,
NSError *_Nullable error))completion;
Synchronize using a configuration
- (void)syncDataWithConfig:(TSDataSyncConfig *)config
onHealthData:(nullable TSDataSyncHealthDataBlock)onHealthData
completion:(void (^)(NSArray<TSHealthData *> *_Nullable results,
NSError *_Nullable error))completion;
Synchronization example
id<TSDataSyncInterface> syncManager = [TopStepComKit sharedInstance].dataSync;
if ([syncManager isSyncing]) {
TSLog(@"[DataSync] A sync is already running");
return;
}
TSDataSyncConfig *config = [TSDataSyncConfig configForDailyDataWithOptions:
(TSDataSyncOptionHeartRate | TSDataSyncOptionBloodOxygen)
startTime:[[NSDate dateWithTimeIntervalSinceNow:-7 * 24 * 60 * 60] timeIntervalSince1970]
endTime:[[NSDate date] timeIntervalSince1970]];
[syncManager syncDataWithConfig:config
onHealthData:^(TSHealthData *typeData) {
if (typeData.fetchError) {
TSLog(@"[DataSync] Type %ld failed: %@", (long)typeData.option,
typeData.fetchError.localizedDescription);
return;
}
TSLog(@"[DataSync] Type %ld finished with %lu values",
(long)typeData.option, (unsigned long)typeData.healthValues.count);
} completion:^(NSArray<TSHealthData *> *results, NSError *error) {
if (error) {
TSLog(@"[DataSync] Fatal error: %@", error.localizedDescription);
return;
}
TSHealthData *heartRate = [TSHealthData findHealthDataWithOption:
TSDataSyncOptionHeartRate fromArray:results];
TSLog(@"[DataSync] Heart-rate result present: %@", heartRate ? @"YES" : @"NO");
}];
Cancel and check status
- (void)cancelSync;
- (BOOL)isSyncing;
cancelSync accepts the request and returns immediately. The original completion later reports eTSErrorSyncCancelled. If no sync is active, the call is ignored. Do not start another sync or release the connection until the completion arrives.
Important notes
- All callbacks run on the main thread.
- An empty
healthValuesarray means that type has no data in the range; it is not a failure. - Raw synchronization can return much more data than daily synchronization; use smaller time ranges when appropriate.
- Set
includeUserInitiatedto NO to exclude manual measurements. startTime == 0uses the database's last sync time;endTime == 0uses the current time.- Invalid configuration, device-busy, authentication, and fatal network errors are reported through the final completion's
error.