---
name: ios-healthkit-integration
description: "HealthKit read/write — steps, heart rate, workouts, sleep, background delivery, permissions flow. Builds HealthKit features the right way: Info.plist permission strings, authorization request flow, HKQuery vs HKObserverQuery, background delivery, HKWorkoutSession for fitness apps, and the privacy-review checklist Apple actually enforces."
license: MIT
---

# iOS HealthKit Integration

A focused skill for wiring HealthKit into a Swift/SwiftUI app correctly the first time — from the permission strings Apple requires through queries, background delivery, and live workout sessions. It is written for iOS developers building fitness, wellness, sleep, or clinical-adjacent apps who need HealthKit code that passes App Review instead of getting rejected for vague privacy copy or misuse of authorization APIs.

## When to use it

- You're adding step, heart-rate, sleep, or workout data to an app and need the full read/write path.
- You need data to keep arriving while the app is backgrounded (e.g. a sync engine or a live activity).
- Your build was rejected for a missing `NSHealthShareUsageDescription`/`NSHealthUpdateUsageDescription`, an over-broad data request, or unclear purpose strings.
- You're building an Apple Watch companion that records workouts with `HKWorkoutSession`/`HKLiveWorkoutBuilder`.

## What it does

The skill scaffolds and reviews the real pieces of a HealthKit integration:

- **Info.plist** — adds `NSHealthShareUsageDescription` (read) and `NSHealthUpdateUsageDescription` (write) with purpose-specific copy, plus the HealthKit capability/entitlement.
- **Authorization** — `HKHealthStore.isHealthDataAvailable()` gating, then `requestAuthorization(toShare:read:)`. It also handles the fact that read authorization status is intentionally opaque (you can't tell if read was denied) and designs flows that don't assume otherwise.
- **Queries** — picks the right tool: `HKSampleQuery` for one-shot fetches, `HKStatisticsQuery`/`HKStatisticsCollectionQuery` for sums and averages (daily step totals), `HKAnchoredObjectQuery` for incremental sync, and `HKObserverQuery` for change notifications.
- **Background delivery** — `enableBackgroundDelivery(for:frequency:)` paired with an `HKObserverQuery` and its completion handler so iOS keeps waking your app.
- **Workouts** — `HKWorkoutSession` + `HKLiveWorkoutBuilder` for watchOS, writing `HKWorkout` with energy and distance.
- **Privacy review** — a checklist mirroring what Apple enforces: data minimization, no advertising use, purpose-string specificity.

## Usage example

```bash
curl -fsSL --create-dirs -o ~/.claude/skills/ios-healthkit-integration/SKILL.md https://claudeskil.com/skills/ios-healthkit-integration/SKILL.md

# then, in your project:
claude "add daily step count + background delivery to my HealthStore service"
```

```swift
let store = HKHealthStore()
let steps = HKQuantityType(.stepCount)
try await store.requestAuthorization(toShare: [], read: [steps])
store.enableBackgroundDelivery(for: steps, frequency: .hourly) { ok, _ in }
```

## Tips & gotchas

- Read status is private by design. Don't branch on "was read denied" — handle empty results gracefully instead.
- Background delivery for most types is throttled to `.hourly` at best; `.immediate` only applies to a few types.
- Always call the `HKObserverQuery` completion handler, or iOS stops delivering updates.
- HealthKit returns nothing in the simulator for many types; test on device or seed data via the Health app.

## FAQ

**Does HealthKit work on iPad?** No. HealthKit is unavailable on iPad — always gate with `isHealthDataAvailable()`.

**Why is my background observer silent?** Usually a missing completion-handler call, the background capability not enabled, or a frequency the type doesn't support.

**Can I store HealthKit data on my own server?** Yes, but you must not use it for advertising or sell it, and your purpose strings must say so.
