HealthKit Integration
The iOS app integrates with Apple HealthKit to automatically import running workouts.
Overview
Running Days reads workout data from HealthKit, the centralized health data store on iOS. This allows automatic import of runs from:
- Apple Watch workouts
- iPhone Workout app
- Third-party fitness apps (Strava, Nike Run Club, etc.)
Required Permissions
The app requests read-only access to:
| Data Type | Purpose |
|---|---|
| Workout (Running) | Core workout data |
| Distance | Run distance |
| Active Energy | Calories burned |
| Heart Rate | HR metrics (optional) |
Setup
1. Enable HealthKit Capability
In Xcode, add the HealthKit capability to your app target.
2. Request Authorization
swift
import HealthKit
class HealthKitManager {
let healthStore = HKHealthStore()
func requestAuthorization() async throws {
let typesToRead: Set<HKSampleType> = [
HKObjectType.workoutType(),
HKQuantityType(.distanceWalkingRunning),
HKQuantityType(.activeEnergyBurned),
HKQuantityType(.heartRate)
]
try await healthStore.requestAuthorization(
toShare: [],
read: typesToRead
)
}
}3. Query Running Workouts
swift
func fetchRunningWorkouts(since date: Date) async throws -> [HKWorkout] {
let runningPredicate = HKQuery.predicateForWorkouts(
with: .running
)
let datePredicate = HKQuery.predicateForSamples(
withStart: date,
end: Date(),
options: .strictStartDate
)
let compound = NSCompoundPredicate(
andPredicateWithSubpredicates: [runningPredicate, datePredicate]
)
let descriptor = HKSampleQueryDescriptor(
predicates: [.workout(compound)],
sortDescriptors: [SortDescriptor(\.startDate, order: .reverse)]
)
return try await descriptor.result(for: healthStore)
}Data Mapping
HealthKit data maps to Running Days as:
| HealthKit | Running Days |
|---|---|
workout.startDate | startTime |
workout.endDate | endTime |
workout.duration | durationSeconds |
totalDistance | distanceMeters |
totalEnergyBurned | energyBurnedKcal |
averageHeartRate | avgHeartRate |
Background Delivery
For automatic sync when new workouts are recorded:
swift
func enableBackgroundDelivery() async throws {
try await healthStore.enableBackgroundDelivery(
for: HKObjectType.workoutType(),
frequency: .immediate
)
}Then handle the background task to sync new workouts.
Privacy Notes
- HealthKit data never leaves the device unencrypted
- Only running workouts are read (not walks, cycles, etc.)
- Users can revoke access anytime in Settings > Privacy > Health
- No health data is shared with third parties