Skip to main content

Daily Activity

The TSDailyActivity module provides comprehensive management of daily activity and exercise data. It enables fetching and setting exercise goals, synchronizing current and historical activity data, and managing reminder configurations for various activity metrics including steps, distance, calories, and exercise duration.

Prerequisites

  • Device must be connected and paired via the TopStepComKit SDK
  • User authentication must be completed
  • Device firmware must support daily activity tracking features
  • For data synchronization, device must have collected activity data

Data Models

TSDailyActivityGoals

Daily exercise goals model managing user's daily activity targets.

PropertyTypeDescription
stepsGoalNSIntegerDaily steps goal. Unit: steps. Range: 0–100,000 (recommended).
caloriesGoalNSIntegerDaily calorie consumption goal. Unit: kilocalories (kcal). Range: 50–3,000 (recommended).
distanceGoalNSIntegerDaily distance goal. Unit: meters (m). Range: 0–100,000 (recommended).
activityDurationGoalNSIntegerDaily activity duration goal. Unit: minutes (min). Range: 0–1,440 (24h).
exerciseDurationGoalNSIntegerDaily exercise duration goal. Unit: minutes (min). Range: 0–1,440 (24h).
exerciseTimesGoalNSIntegerDaily exercise frequency goal. Unit: times. Range: 1–50 (recommended).
activityTimesGoalNSIntegerDaily activity frequency goal. Unit: times. Range: 1–100 (recommended).

TSDailyActivityItem

Daily activity and exercise data model representing activity statistics for a specific time period.

PropertyTypeDescription
stepsNSIntegerTotal step count for the period. Unit: steps.
caloriesNSIntegerTotal calories burned. Unit: small calories (cal). Includes basal metabolic rate and activity-induced calorie burn.
distanceNSIntegerTotal distance covered. Unit: meters (m).
activityDurationNSIntegerTotal activity duration. Unit: seconds. Includes all movement exceeding minimum activity threshold.
exercisesDurationNSIntegerTotal exercise duration. Unit: seconds. Only dedicated exercise sessions.
exercisesTimesNSIntegerNumber of distinct exercise sessions. Unit: times.
activityTimesNSIntegerNumber of distinct activity sessions. Unit: times.

TSActivityDailyModel

Daily aggregated activity model representing one day's complete activity data.

PropertyTypeDescription
stepsNSIntegerDaily aggregated steps. Sum of all TSDailyActivityItem entries for the day.
caloriesNSIntegerDaily aggregated calories. Unit: small calories (cal). Read-only.
distanceNSIntegerDaily aggregated distance. Unit: meters (m). Read-only.
activityDurationNSIntegerDaily aggregated activity duration. Unit: seconds. Read-only.
activityTimesNSIntegerDaily aggregated activity times. Read-only.
exercisesDurationNSIntegerDaily aggregated exercise duration. Unit: seconds. Read-only.
exercisesTimesNSIntegerDaily aggregated exercise times. Read-only.
activityItemsNSArray<TSDailyActivityItem *> *Array of daily activity items for the day, ordered by time ascending.

TSDailyActivityReminder

Daily exercise reminder switches model managing reminder configurations for activity goals.

PropertyTypeDescription
stepsReminderEnabledBOOLSteps goal reminder enabled. When enabled, device notifies when daily steps goal is reached.
caloriesReminderEnabledBOOLCalories goal reminder enabled. When enabled, device notifies when daily calories goal is reached.
distanceReminderEnabledBOOLDistance goal reminder enabled. When enabled, device notifies when daily distance goal is reached.
activityTimesReminderEnabledBOOLActivity times goal reminder enabled. When enabled, device notifies when daily activity times goal is reached.
activityDurationReminderEnabledBOOLActivity duration goal reminder enabled. When enabled, device notifies when daily activity duration goal is reached.
exerciseTimesReminderEnabledBOOLExercise times goal reminder enabled. When enabled, device notifies when daily exercise times goal is reached.
exerciseDurationReminderEnabledBOOLExercise duration goal reminder enabled. When enabled, device notifies when daily exercise duration goal is reached.

Enumerations

TSDailyActivityType

Daily activity type enumeration defining types of daily activities that can be displayed on the device.

ValueDescription
TSDailyActivityTypeStepCountStep count activity type.
TSDailyActivityTypeExerciseDurationExercise duration activity type.
TSDailyActivityTypeActivityCountActivity count activity type.
TSDailyActivityTypeActiveDurationActive duration activity type.
TSDailyActivityTypeDistanceDistance activity type.
TSDailyActivityTypeCaloriesCalories activity type.

Callback Types

TSCompletionBlock

typedef void (^TSCompletionBlock)(NSError *_Nullable error);

Completion block indicating operation success or failure.

ParameterTypeDescription
errorNSError *Error object if operation failed, nil if successful.

Activity Types Completion Block

void (^)(NSArray<NSNumber *> *_Nullable activityTypes, NSError *_Nullable error)

Completion block returning supported activity types.

ParameterTypeDescription
activityTypesNSArray<NSNumber *> *Array of supported TSDailyActivityType enum values as NSNumber objects.
errorNSError *Error object if operation failed.

Goals Completion Block

void (^)(TSDailyActivityGoals *_Nullable goals, NSError *_Nullable error)

Completion block returning daily exercise goals.

ParameterTypeDescription
goalsTSDailyActivityGoals *Current daily exercise goals model.
errorNSError *Error object if operation failed.

Goals and Reminder Completion Block

void (^)(TSDailyActivityGoals *_Nullable goals, TSDailyActivityReminder *_Nullable reminder, NSError *_Nullable error)

Completion block returning both goals and reminder configuration.

ParameterTypeDescription
goalsTSDailyActivityGoals *Current daily exercise goals model.
reminderTSDailyActivityReminder *Current reminder configuration model.
errorNSError *Error object if operation failed.

Reminder Completion Block

void (^)(TSDailyActivityReminder *_Nullable reminder, NSError *_Nullable error)

Completion block returning reminder configuration.

ParameterTypeDescription
reminderTSDailyActivityReminder *Current reminder switches model.
errorNSError *Error object if operation failed.

Today Activity Completion Block

void (^)(TSActivityDailyModel *_Nullable todayActivity, NSError *_Nullable error)

Completion block returning today's activity data.

ParameterTypeDescription
todayActivityTSActivityDailyModel *Today's aggregated activity data.
errorNSError *Error object if operation failed.

Raw Activity Items Completion Block

void (^)(NSArray<TSDailyActivityItem *> *_Nullable activityItems, NSError *_Nullable error)

Completion block returning raw activity measurement items.

ParameterTypeDescription
activityItemsNSArray<TSDailyActivityItem *> *Array of raw daily activity items.
errorNSError *Error object if operation failed.

Daily Models Completion Block

void (^)(NSArray<TSActivityDailyModel *> *_Nullable dailyModels, NSError *_Nullable error)

Completion block returning daily aggregated models.

ParameterTypeDescription
dailyModelsNSArray<TSActivityDailyModel *> *Array of daily aggregated activity models.
errorNSError *Error object if operation failed.

API Reference

Fetch supported daily activity types

Retrieves the list of daily activity types that the device supports and displays, used to configure which activity rings are shown in the main interface.

- (void)fetchSupportedDailyActivityTypesWithCompletion:(void(^)(NSArray<NSNumber *> *_Nullable activityTypes, NSError *_Nullable error))completion;
ParameterTypeDescription
completionvoid (^)(NSArray<NSNumber *> *_Nullable activityTypes, NSError *_Nullable error)Completion block returning array of supported activity types or error.

Example:

id<TSDailyActivityInterface> dailyActivityInterface = [topStepKit dailyActivityInterface];

[dailyActivityInterface fetchSupportedDailyActivityTypesWithCompletion:^(NSArray<NSNumber *> * _Nullable activityTypes, NSError * _Nullable error) {
if (error) {
TSLog(@"Failed to fetch supported activity types: %@", error.localizedDescription);
return;
}

TSLog(@"Supported activity types count: %lu", (unsigned long)activityTypes.count);
for (NSNumber *typeNum in activityTypes) {
TSDailyActivityType type = (TSDailyActivityType)[typeNum integerValue];
TSLog(@"Activity type: %ld", (long)type);
}
}];

Get current daily exercise goals

Retrieves the user's current daily exercise goals from the device, including steps, calories, distance, and activity/exercise durations.

- (void)fetchDailyExerciseGoalsWithCompletion:(void(^)(TSDailyActivityGoals *_Nullable goals,NSError *_Nullable error))completion;
ParameterTypeDescription
completionvoid (^)(TSDailyActivityGoals *_Nullable goals, NSError *_Nullable error)Completion block returning current goals or error.

Example:

id<TSDailyActivityInterface> dailyActivityInterface = [topStepKit dailyActivityInterface];

[dailyActivityInterface fetchDailyExerciseGoalsWithCompletion:^(TSDailyActivityGoals * _Nullable goals, NSError * _Nullable error) {
if (error) {
TSLog(@"Failed to fetch exercise goals: %@", error.localizedDescription);
return;
}

TSLog(@"Steps goal: %ld", (long)goals.stepsGoal);
TSLog(@"Calories goal: %ld kcal", (long)goals.caloriesGoal);
TSLog(@"Distance goal: %ld meters", (long)goals.distanceGoal);
TSLog(@"Exercise duration goal: %ld minutes", (long)goals.exerciseDurationGoal);
}];

Set daily exercise goals

Writes user's daily exercise goals to the device, including steps, calories, distance, and activity/exercise durations.

- (void)pushDailyExerciseGoals:(TSDailyActivityGoals *)goalsModel
completion:(TSCompletionBlock)completion;
ParameterTypeDescription
goalsModelTSDailyActivityGoals *Model containing goals to set.
completionTSCompletionBlockCompletion block indicating success or error.

Example:

id<TSDailyActivityInterface> dailyActivityInterface = [topStepKit dailyActivityInterface];

TSDailyActivityGoals *goals = [[TSDailyActivityGoals alloc] init];
goals.stepsGoal = 10000;
goals.caloriesGoal = 500;
goals.distanceGoal = 8000;
goals.exerciseDurationGoal = 30;
goals.exerciseTimesGoal = 1;
goals.activityDurationGoal = 60;
goals.activityTimesGoal = 10;

[dailyActivityInterface pushDailyExerciseGoals:goals completion:^(NSError * _Nullable error) {
if (error) {
TSLog(@"Failed to set exercise goals: %@", error.localizedDescription);
} else {
TSLog(@"Exercise goals set successfully");
}
}];

Fetch daily exercise goals and reminders atomically

Retrieves both daily exercise goals and their reminder switches in a single request for data consistency.

- (void)fetchDailyExerciseAllWithCompletion:(void(^)(TSDailyActivityGoals *_Nullable goals,
TSDailyActivityReminder *_Nullable reminder,
NSError *_Nullable error))completion;
ParameterTypeDescription
completionvoid (^)(TSDailyActivityGoals *_Nullable goals, TSDailyActivityReminder *_Nullable reminder, NSError *_Nullable error)Completion block returning goals model, reminder model and error.

Example:

id<TSDailyActivityInterface> dailyActivityInterface = [topStepKit dailyActivityInterface];

[dailyActivityInterface fetchDailyExerciseAllWithCompletion:^(TSDailyActivityGoals * _Nullable goals, TSDailyActivityReminder * _Nullable reminder, NSError * _Nullable error) {
if (error) {
TSLog(@"Failed to fetch goals and reminders: %@", error.localizedDescription);
return;
}

TSLog(@"Steps goal: %ld, Reminder enabled: %@", (long)goals.stepsGoal, reminder.stepsReminderEnabled ? @"YES" : @"NO");
TSLog(@"Calories goal: %ld, Reminder enabled: %@", (long)goals.caloriesGoal, reminder.caloriesReminderEnabled ? @"YES" : @"NO");
}];

Push daily exercise goals and reminders atomically

Aggregates both goals and reminder switches into a single underlying write to avoid intermediate inconsistent states.

- (void)pushDailyExerciseGoals:(TSDailyActivityGoals *)goalsModel
reminder:(TSDailyActivityReminder *)reminder
completion:(TSCompletionBlock)completion;
ParameterTypeDescription
goalsModelTSDailyActivityGoals *Goals model to set.
reminderTSDailyActivityReminder *Reminder switches model to set.
completionTSCompletionBlockCompletion block indicating success or error.

Example:

id<TSDailyActivityInterface> dailyActivityInterface = [topStepKit dailyActivityInterface];

TSDailyActivityGoals *goals = [[TSDailyActivityGoals alloc] init];
goals.stepsGoal = 10000;
goals.caloriesGoal = 500;
goals.distanceGoal = 8000;
goals.exerciseDurationGoal = 30;

TSDailyActivityReminder *reminder = [[TSDailyActivityReminder alloc] init];
reminder.stepsReminderEnabled = YES;
reminder.caloriesReminderEnabled = YES;
reminder.distanceReminderEnabled = YES;
reminder.exerciseDurationReminderEnabled = YES;

[dailyActivityInterface pushDailyExerciseGoals:goals reminder:reminder completion:^(NSError * _Nullable error) {
if (error) {
TSLog(@"Failed to set goals and reminders: %@", error.localizedDescription);
} else {
TSLog(@"Goals and reminders set successfully");
}
}];

Get current daily exercise reminder switches

Retrieves reminder switches for goals: steps, calories, distance, activity duration, exercise duration and exercise frequency.

- (void)fetchDailyExerciseReminderConfigWithCompletion:(void(^)(TSDailyActivityReminder *_Nullable reminder, NSError *_Nullable error))completion;
ParameterTypeDescription
completionvoid (^)(TSDailyActivityReminder *_Nullable reminder, NSError *_Nullable error)Completion block returning reminder switches or error.

Example:

id<TSDailyActivityInterface> dailyActivityInterface = [topStepKit dailyActivityInterface];

[dailyActivityInterface fetchDailyExerciseReminderConfigWithCompletion:^(TSDailyActivityReminder * _Nullable reminder, NSError * _Nullable error) {
if (error) {
TSLog(@"Failed to fetch reminder config: %@", error.localizedDescription);
return;
}

TSLog(@"Steps reminder: %@", reminder.stepsReminderEnabled ? @"Enabled" : @"Disabled");
TSLog(@"Calories reminder: %@", reminder.caloriesReminderEnabled ? @"Enabled" : @"Disabled");
TSLog(@"Exercise duration reminder: %@", reminder.exerciseDurationReminderEnabled ? @"Enabled" : @"Disabled");
}];

Set daily exercise reminder switches

Writes reminder switches for steps, calories, distance, activity/exercise durations and exercise frequency.

- (void)pushDailyExerciseReminder:(TSDailyActivityReminder *)reminder
completion:(TSCompletionBlock)completion;
ParameterTypeDescription
reminderTSDailyActivityReminder *Reminder switches model to set.
completionTSCompletionBlockCompletion block indicating success or error.

Example:

id<TSDailyActivityInterface> dailyActivityInterface = [topStepKit dailyActivityInterface];

TSDailyActivityReminder *reminder = [[TSDailyActivityReminder alloc] init];
reminder.stepsReminderEnabled = YES;
reminder.caloriesReminderEnabled = YES;
reminder.distanceReminderEnabled = YES;
reminder.activityDurationReminderEnabled = YES;
reminder.exerciseDurationReminderEnabled = YES;
reminder.exerciseTimesReminderEnabled = YES;
reminder.activityTimesReminderEnabled = YES;

[dailyActivityInterface pushDailyExerciseReminder:reminder completion:^(NSError * _Nullable error) {
if (error) {
TSLog(@"Failed to set reminder config: %@", error.localizedDescription);
} else {
TSLog(@"Reminder config set successfully");
}
}];

Synchronize today's daily exercise data

Retrieves the current day's activity data from the device, including step count, distance, calories, activity duration, and exercise sessions information.

- (void)syncTodayDailyExerciseDataCompletion:(void (^)(TSActivityDailyModel *_Nullable todayActivity, NSError *_Nullable error))completion;
ParameterTypeDescription
completionvoid (^)(TSActivityDailyModel *_Nullable todayActivity, NSError *_Nullable error)Completion block with today's exercise data or error.

Example:

id<TSDailyActivityInterface> dailyActivityInterface = [topStepKit dailyActivityInterface];

[dailyActivityInterface syncTodayDailyExerciseDataCompletion:^(TSActivityDailyModel * _Nullable todayActivity, NSError * _Nullable error) {
if (error) {
TSLog(@"Failed to sync today's data: %@", error.localizedDescription);
return;
}

TSLog(@"Today's steps: %ld", (long)todayActivity.steps);
TSLog(@"Today's calories: %ld", (long)todayActivity.calories);
TSLog(@"Today's distance: %ld meters", (long)todayActivity.distance);
TSLog(@"Today's activity duration: %ld seconds", (long)todayActivity.activityDuration);
TSLog(@"Activity items count: %lu", (unsigned long)todayActivity.activityItems.count);
}];

Synchronize raw daily activity data within time range

Retrieves historical daily activity data for the specified time range. Each day's data is represented as a separate TSDailyActivityItem object.

- (void)syncRawDataFromStartTime:(NSTimeInterval)startTime
endTime:(NSTimeInterval)endTime
completion:(nonnull void (^)(NSArray<TSDailyActivityItem *> *_Nullable activityItems, NSError *_Nullable error))completion;
ParameterTypeDescription
startTimeNSTimeIntervalStart time for data synchronization (timestamp in seconds since 1970).
endTimeNSTimeIntervalEnd time for data synchronization (timestamp in seconds since 1970).
completionvoid (^)(NSArray<TSDailyActivityItem *> *_Nullable activityItems, NSError *_Nullable error)Completion block with synchronized raw daily activity measurement items or error.

Example:

id<TSDailyActivityInterface> dailyActivityInterface = [topStepKit dailyActivityInterface];

NSDate *now = [NSDate date];
NSDate *sevenDaysAgo = [now dateByAddingTimeInterval:-7 * 24 * 60 * 60];

[dailyActivityInterface syncRawDataFromStartTime:[sevenDaysAgo timeIntervalSince1970]
endTime:[now timeIntervalSince1970]
completion:^(NSArray<TSDailyActivityItem *> * _Nullable activityItems, NSError * _Nullable error) {
if (error) {
TSLog(@"Failed to sync raw data: %@", error.localizedDescription);
return;
}

TSLog(@"Raw activity items count: %lu", (unsigned long)activityItems.count);
for (TSDailyActivityItem *item in activityItems) {
TSLog(@"Steps: %ld, Distance: %ld, Calories: %ld", (long)item.steps, (long)item.distance, (long)item.calories);
}
}];

Synchronize raw daily activity data from start time until now

Retrieves historical daily activity data from the specified start time until the current time.

- (void)syncRawDataFromStartTime:(NSTimeInterval)startTime
completion:(nonnull void (^)(NSArray<TSDailyActivityItem *> *_Nullable activityItems, NSError *_Nullable error))completion;
ParameterTypeDescription
startTimeNSTimeIntervalStart time for data synchronization (timestamp in seconds since 1970).
completionvoid (^)(NSArray<TSDailyActivityItem *> *_Nullable activityItems, NSError *_Nullable error)Completion block with synchronized raw daily activity measurement items or error.

Example:

id<TSDailyActivityInterface> dailyActivityInterface = [topStepKit dailyActivityInterface];

NSDate *thirtyDaysAgo = [[NSDate date] dateByAddingTimeInterval:-30 * 24 * 60 * 60];

[dailyActivityInterface syncRawDataFromStartTime:[thirtyDaysAgo timeIntervalSince1970]
completion:^(NSArray<TSDailyActivityItem *> * _Nullable activityItems, NSError * _Nullable error) {
if (error) {
TSLog(@"Failed to sync raw data: %@", error.localizedDescription);
return;
}

NSInteger totalSteps = 0;
for (TSDailyActivityItem *item in activityItems) {
totalSteps += item.steps;
}
TSLog(@"Total steps in last 30 days: %ld", (long)totalSteps);
}];

Synchronize daily aggregated activity data within time range

Synchronizes daily aggregated activity data within the given time range. Time parameters are automatically normalized to day boundaries.

- (void)syncDailyDataFromStartTime:(NSTimeInterval)startTime
endTime:(NSTimeInterval)endTime
completion:(nonnull void (^)(NSArray<TSActivityDailyModel *> *_Nullable dailyModels, NSError *_Nullable error))completion;
ParameterTypeDescription
startTimeNSTimeIntervalStart time for data synchronization. Will be normalized to 00:00:00 of the specified day. Must be earlier than endTime.
endTimeNSTimeIntervalEnd time for data synchronization. Will be normalized to 23:59:59 of the specified day. Must be later than startTime and not in the future.
completionvoid (^)(NSArray<TSActivityDailyModel *> *_Nullable dailyModels, NSError *_Nullable error)Completion block with synchronized daily activity models or error.

Example:

id<TSDailyActivityInterface> dailyActivityInterface = [topStepKit dailyActivityInterface];

NSDate *now = [NSDate date];
NSDate *sevenDaysAgo = [now dateByAddingTimeInterval:-7 * 24 * 60 * 60];

[dailyActivityInterface syncDailyDataFromStartTime:[sevenDaysAgo timeIntervalSince1970]
endTime:[now timeIntervalSince1970]
completion:^(NSArray<TSActivityDailyModel *> * _Nullable dailyModels, NSError * _Nullable error) {
if (error) {
TSLog(@"Failed to sync daily data: %@", error.localizedDescription);
return;
}

TSLog(@"Daily models count: %lu", (unsigned long)dailyModels.count);
for (TSActivityDailyModel *dailyModel in dailyModels) {
NSDate *date = [NSDate dateWithTimeIntervalSince1970:dailyModel.startTime];
TSLog(@"Date: %@, Steps: %ld, Calories: %ld, Duration: %ld seconds",
date, (long)dailyModel.steps, (long)dailyModel.calories, (long)dailyModel.activityDuration);
}
}];

Synchronize daily aggregated activity data from start time until now

Synchronizes daily aggregated activity data from the start time to the current time. Start time is automatically normalized to 00:00:00 of the specified day.

- (void)syncDailyDataFromStartTime:(NSTimeInterval)startTime
completion:(nonnull void (^)(NSArray<TSActivityDailyModel *> *_Nullable dailyModels, NSError *_Nullable error))completion;
ParameterTypeDescription
startTimeNSTimeIntervalStart time for data synchronization. Will be normalized to 00:00:00 of the specified day.
completionvoid (^)(NSArray<TSActivityDailyModel *> *_Nullable dailyModels, NSError *_Nullable error)Completion block with synchronized daily activity models or error.

Example:

id<TSDailyActivityInterface> dailyActivityInterface = [topStepKit dailyActivityInterface];

NSDate *startDate = [NSDate dateWithTimeIntervalSince1970:1704067200]; // 2024-01-01

[dailyActivityInterface syncDailyDataFromStartTime:[startDate timeIntervalSince1970]
completion:^(NSArray<TSActivityDailyModel *> * _Nullable dailyModels, NSError * _Nullable error) {
if (error) {
TSLog(@"Failed to sync daily data: %@", error.localizedDescription);
return;
}

NSInteger totalSteps = 0;
NSInteger totalCalories = 0;
for (TSActivityDailyModel *dailyModel in dailyModels) {
totalSteps += dailyModel.steps;
totalCalories += dailyModel.calories;
}
TSLog(@"Total steps since start: %ld", (long)totalSteps);
TSLog(@"Total calories since start: %ld", (long)totalCalories);
}];

Important Notes

  1. All completion blocks are executed on the main thread. Ensure UI updates are performed within these blocks for thread safety.

  2. Time parameters in synchronization methods accept timestamps in seconds since January 1, 1970 (Unix epoch). Use [NSDate timeIntervalSince1970] to convert between NSDate and timestamps.

  3. For syncDailyDataFromStartTime:endTime:completion: method, start and end times are automatically normalized to day boundaries (00:00:00 to 23:59:59). Provide any time within a day to retrieve that day's aggregated data.

  4. The syncRawDataFromStartTime:endTime:completion: method returns measurement items representing raw, detailed data points, while syncDailyDataFromStartTime:endTime:completion: returns daily aggregated models with calculated totals.

  5. Properties marked as readonly in TSActivityDailyModel (calories, distance, activityDuration, activityTimes, exercisesDuration, exercisesTimes) are automatically calculated from the aggregation of activityItems and cannot be directly modified.

  6. Goal ranges are recommended values. Values outside recommended ranges may affect accuracy of health analysis. Validate user input before setting goals.

  7. Activity duration is measured in seconds and can be converted to minutes by dividing by 60. Exercise duration follows the same convention.

  8. The fetchDailyExerciseAllWithCompletion: and pushDailyExerciseGoals:reminder:completion: methods provide atomic operations, ensuring data consistency between goals and reminders.

  9. Before synchronizing historical data, verify that the device has sufficient storage capacity and that the requested time range is not too large to avoid timeout.

  10. For optimal performance, use separate calls to fetch goals, reminders, and activity data. Combine operations only when data consistency between goals and reminders is critical.