Step Tracking Dashboard
The goal: a dashboard with today's steps against the member's daily goal and a chart of the last seven days, kept up to date by SmartWalking's automatic background sync from Health Connect (Android) or HealthKit (iOS).
The flow
-
Check the member's program. SmartWalking is part of the member's program. Confirm the member has it before you offer the setup. APIs:
programs().getAvailablePrograms. -
Connect the health source. One call asks the member for access to their step data, registers them with SmartWalking and turns on automatic sync. Skip it for a member who is already connected. APIs:
smartWalking().getRegisteredProfile,smartWalking().connectGoogleHealthConnect(Android),smartWalking().connectAppleHealthKit(iOS). -
Load the goal and the steps. Read the member's daily step goal and the month's activity, and add up the steps per day for the progress ring and the weekly chart. APIs:
smartWalking().getDailyStepGoal,activities().get. -
Refresh after each sync. Watch the sync events and reload the dashboard once a sync has been processed. Offer pull-to-refresh with a manual sync. APIs:
smartWalking().syncEvents(Android) /smartWalking().subscribeToEvents(iOS),SmartWalkingEvent.SyncProcessed,smartWalking().syncSteps. -
Keep syncing in the background. Automatic sync keeps running after the app is closed. It belongs to the member's session, so turn it on again after the next sign-in. APIs:
smartWalking().enableAutoSync,smartWalking().disableAutoSync,smartWalking().isAutoSyncEnabled.
Example: connect and refresh on sync
- Android (Kotlin)
- iOS (Swift)
lifecycleScope.launch {
try {
// activity: the current ComponentActivity; Health Connect shows its permission screen
val profile = AFCore.smartWalking().getRegisteredProfile()?.takeIf { it.isConnected }
?: AFCore.smartWalking().connectGoogleHealthConnect(activity, deviceId)
if (!profile.isConnected) return@launch showHealthAccessNeeded()
val goal = AFCore.smartWalking().getDailyStepGoal()
showDashboard(goal)
AFCore.smartWalking().syncEvents.collect { event ->
if (event is SmartWalkingEvent.SyncProcessed) showDashboard(goal)
}
} catch (t: Throwable) {
showError(t)
}
}
Task { @MainActor in
do {
var profile = try await AFCore.shared.smartWalking().getRegisteredProfile()
if profile?.isConnected != true {
// Shows the HealthKit sheet, registers the member and turns on auto-sync
profile = try await AFCore.shared.smartWalking().connectAppleHealthKit(deviceId: deviceId)
}
guard profile?.isConnected == true else { showHealthAccessNeeded(); return }
let goal = try await AFCore.shared.smartWalking().getDailyStepGoal()
showDashboard(goal: goal)
subscription = AFCore.shared.smartWalking().subscribeToEvents(
onEvent: { event in
Task { @MainActor in
if event is SmartWalkingEvent.SyncProcessed { showDashboard(goal: goal) }
}
},
onError: { _ in }
)
} catch {
showError(error)
}
}
Learn more
- SmartWalking and Activities -- the capabilities this recipe uses.
- API Reference -- every call named above.
- Complete, step-by-step integration guides are in AIDE Docs.