How does HealthKit handle authorization and units, and what should an app know about Core Motion and sensor availability?
Predict first
A mile in metres converts back to what, and what are the HealthKit write-status values? Are accelerometer and step counting available in the simulator?
import HealthKit
import CoreMotion
let q = HKQuantity(unit: .meter(), doubleValue: 1609.344)
print(q.doubleValue(for: .mile()))
print(HKAuthorizationStatus.notDetermined.rawValue, HKAuthorizationStatus.sharingDenied.rawValue, HKAuthorizationStatus.sharingAuthorized.rawValue)
print(CMMotionManager().isAccelerometerAvailable, CMPedometer.isStepCountingAvailable())
- 1.0, then 0 1 2, then false false
- 1609.344, then 1 2 3, then true true
- 1.0, then 0 1 2, then true true
Mental model. HealthKit’s read denial is a one-way mirror: you ask to see a drawer and get an empty hand back whether the drawer is empty or locked, so you cannot learn anything from being refused.
HealthKit is the central, encrypted store of health data shared among apps. You check HKHealthStore.isHealthDataAvailable() first (false on devices without Health, such as some iPads), request access for specific types (requestAuthorization(toShare:read:), with an NSHealthShareUsageDescription and NSHealthUpdateUsageDescription and the HealthKit capability), and the user grants or denies each type separately. The key privacy design: for read access the app cannot tell whether it was denied. A denied read simply returns no data, identical to “there is no data”, so an app must not deduce the user’s health from what permission they refused. authorizationStatus(for:) reports only the write (sharing) permission: notDetermined (0), sharingDenied (1), sharingAuthorized (2). Data is typed: HKQuantityType (steps, heart rate, distance), HKCategoryType (sleep analysis), HKWorkoutType, and HKCharacteristicType (date of birth). Values are HKQuantity with units that convert correctly: HKQuantity(unit: .meter(), doubleValue: 1609.344).doubleValue(for: .mile()) is 1.0, so store and query in standard units and convert for display with the user’s locale. Query with HKSampleQuery, HKStatisticsQuery and HKStatisticsCollectionQuery (aggregation by day), observe changes with HKObserverQuery or an HKAnchoredObjectQuery (which uses an anchor so you only get new samples), and enable background delivery to be woken when data arrives. Write with HKQuantitySample and workouts via HKWorkoutBuilder.
Constraints and pitfalls: health data is locked while the device is locked (a background wake may not be able to read it), HealthKit data must not be used for advertising or sold, App Review requires a clear privacy policy and justified types, and it is not available in the simulator’s real sensors. Core Motion (CMMotionManager, CMPedometer, CMAltimeter, CMMotionActivityManager) reads accelerometer, gyroscope and magnetometer streams and pedometer and activity data; always check availability first (isAccelerometerAvailable, CMPedometer.isStepCountingAvailable(), both false in the simulator), request motion permission through the usage description (NSMotionUsageDescription), choose the lowest update interval that serves the feature (high rates drain the battery), stop updates when not needed, and use the pedometer’s historical queries rather than counting steps yourself. A single CMMotionManager instance should be shared. Design principles: request only the types you use, explain each in context, handle “no data” as a normal case (it may be a denial), keep data on device or encrypted, and do not make medical claims without the proper regulatory footing.
1609.344 metres is exactly one mile. The write statuses are 0, 1 and 2, and the simulator has no motion hardware.
Common traps
- Treating “no samples returned” as “the user has no data”. It may be a denial; design for the unknown.
- Polling sensors at a high rate in the background. It drains the battery; use the lowest interval and stop when done.
They might follow up with
- What does
authorizationStatus(for:)tell you? Only the write permission; read permission is deliberately hidden. - How do you convert HealthKit units safely? Use
HKUnitconversions on anHKQuantity, for example metres to miles.
Related questions
- 17.3.1 How do the Contacts, EventKit and Photos frameworks gate access, and how should an app handle limited or…
- 17.7.1 How do you approach an unfamiliar Apple framework: what do you check before you write code, and how do you…
← How do the Contacts, EventKit and Photos frameworks gate access, and…