“We support Apple Health” is one of the most commonly overstated sentences in health product engineering. It sounds like a data guarantee. It is actually a statement about an API you have permission to call.
HealthKit exposes well over a hundred data types [1]. An iPhone sitting in a pocket, with no Apple Watch and no connected devices, writes about a dozen of them. Everything else in that catalogue is either produced by hardware your user may not own, or typed in by hand, or never populated at all. The API surface and the data surface are different sizes, and the gap between them is where feature plans quietly die.
This is a breakdown of which types come from where, how to tell them apart in code, and what it means for a product when the majority of your users own only the phone.
Three sources wearing one uniform
Every sample in HealthKit arrives through the same interface regardless of origin, which makes provenance invisible unless you go looking for it.
There are really three populations of data in the Health app, and they behave completely differently:
| Origin | What it means | Reliability |
|---|---|---|
| Measured by the phone | Derived from the iPhone’s own motion sensors | Always present, quality varies with carry habits |
| Measured by a Watch or device | Requires hardware the user bought separately | Present only for the subset who own it |
| Entered by a person or app | Someone typed it, or an app wrote it | Present only if the user does the work |
A weight reading, a step count and a heart rate all arrive as HKQuantitySample objects with a type, a value, a unit and a date range. Nothing in that shape tells you that the first was typed in three weeks ago, the second came from a motion coprocessor, and the third does not exist for this user at all. You have to ask.
Here is the split for the types products actually reach for:
| Data type | Where it originates |
|---|---|
| Step count | iPhone motion sensors, and the Watch when worn |
| Walking and running distance | iPhone motion sensors, and the Watch when worn |
| Flights climbed | Barometer, in the iPhone and in the Watch |
| Walking speed, walking step length | iPhone motion sensors |
| Walking asymmetry, double support percentage | iPhone motion sensors |
| Stair ascent and descent speed | iPhone motion sensors |
| Walking steadiness | iPhone motion sensors |
| Six-minute walk distance | iPhone motion sensors |
| Heart rate, resting and walking heart rate | Apple Watch, or another wearable |
| Heart rate variability | Apple Watch, or another wearable |
| Blood oxygen | Apple Watch, or another wearable |
| ECG | Apple Watch |
| Wrist temperature | Apple Watch |
| VO2 max, cardio fitness | Apple Watch |
| Sleep stages | Apple Watch, or another wearable |
| Weight, height, body composition | Typed in, or a connected scale |
| Nutrition, hydration, caffeine | Typed in, or a logging app |
| Blood glucose, blood pressure | A connected meter or cuff |
| Menstrual cycle and reproductive | Typed in |
| State of Mind, PHQ-9, GAD-7 | Typed in |
Read the top block on its own and that is your phone-only product. Everything below it is a dependency on hardware your user bought separately, or on a habit they have to keep up.
One thing this table does not say. Any app with write permission can put almost anything into HealthKit, so a heart rate sample can exist on a device with no Watch if some other app wrote it. The column above is about what originates where, not about what is technically possible to store. That distinction matters when you are deciding whether to trust a value, which is what the provenance section below is for.
What the phone measures on its own
The iPhone’s contribution is motion. That is a narrower category than people expect, and a richer one.
An iPhone contains an accelerometer, a gyroscope, a barometer and a motion coprocessor that runs continuously at low power. From that hardware alone, without any wearable, HealthKit receives:
- Step count, the type most products start with
- Walking and running distance, estimated from stride and step cadence
- Flights climbed, which is the barometer detecting pressure changes rather than the accelerometer counting stairs
- The mobility metrics, added progressively from iOS 14: walking speed, walking step length, walking asymmetry percentage, walking double support percentage, stair ascent and descent speed, and six-minute walk distance
- Walking steadiness, a composite gait-quality classification introduced in iOS 15
- Headphone audio exposure, when headphones are connected
The mobility set is the interesting part, and it is routinely overlooked. These are not step counts by another name. Walking asymmetry is the percentage of time a person’s gait is uneven; double support percentage is the proportion of a stride where both feet are on the ground. Both are clinical gait measures that used to require a lab, and an iPhone in a pocket produces them passively for anyone who walks.
Worth knowing: the mobility metrics are among the least-used data in HealthKit, because most products stop at step count. If you are looking for signal that competitors are not already surfacing, this is where it is, and it requires no additional hardware from the user.
What only exists if they own a Watch
Every cardiovascular and sleep-architecture type in HealthKit originates at the wrist. An iPhone has no sensor that can produce them.
This is the boundary that catches feature plans. The following require an Apple Watch, or a third-party device writing into HealthKit on the user’s behalf:
- Heart rate, resting heart rate, walking heart rate average
- Heart rate variability, the input to most readiness and recovery models
- Blood oxygen, ECG, and wrist temperature
- Sleep stages, the REM, core and deep breakdown
- VO2 max and cardio fitness
- Exercise minutes and stand hours, the Activity ring metrics
There is no estimation fallback. If a user has no Watch, a heart rate query returns an empty array, not an approximation. That is the correct behaviour, but it means any product whose core loop depends on HRV is a product that does not function for a user without a wearable.
Sleep deserves a note of its own, because it is the type teams most often assume the phone provides. Apple’s own iPhone-based sleep tracking changed materially, and we covered what that removal meant for products that depended on it in smartphone sleep tracking. The short version: do not assume a phone-only user has sleep data in HealthKit simply because the Health app has a Sleep section.
What is really just a text field
A large share of HealthKit’s type catalogue is storage, not sensing.
Weight, height, body fat percentage, nutrition across sixty-plus nutrient types, menstrual cycle logging, State of Mind, PHQ-9 and GAD-7 assessment scores, medications: none of these are measured by anything. They are values a person or an app writes down.
That is not a criticism. Structured storage for self-reported data is genuinely useful, and the mental health assessments in particular are a well-designed addition. But it changes what a data type means for your planning. “HealthKit supports nutrition” is true and tells you nothing about whether a given user has any nutrition data, because that depends entirely on whether they have been logging meals in some other app for the past six months.
The planning question for every type is not “does HealthKit support this” but “what would have to be true about this user for this to be populated”.
The API will not tell you which problem you have
An empty result is ambiguous between three completely different situations, and HealthKit does not disambiguate them on purpose.
Query for heart rate over the last week and receive nothing. That means one of:
- The user denied read permission for heart rate
- The user owns no device that produces heart rate
- The user owns a Watch, granted permission, and simply did not wear it
HealthKit will not tell you which. The permission model is deliberately asymmetric here: an app can see whether it has been granted write access, but read denials are indistinguishable from absent data, because reporting the denial would leak the fact that a user chose to hide something. That is a good privacy decision and an awkward engineering one.
The practical consequence is that your onboarding cannot be a permission prompt followed by an assumption. You need a positive check for whether meaningful data actually arrived, and a path that works when it did not. This is the same problem as the ambiguity of missing data anywhere in a health pipeline, just in its most concentrated form.
Reading provenance properly
Every sample carries its own source and device metadata. Using it is the difference between a step count you can trust and three step counts you accidentally added together.
HKSample exposes two things worth reading on every sample you ingest:
// Which app or system wrote this sample, and from what hardware.
let source = sample.sourceRevision // HKSourceRevision
let bundleId = source.source.bundleIdentifier
let device = sample.device // HKDevice?, nil for manual entry
// "Apple Watch" vs "iPhone" vs a third-party app, distinguishable here
// and nowhere else in the sample.
let model = device?.modelTwo things follow from reading it. First, you can tell a phone-derived step count from a Watch-derived one, which matters because they disagree: the same walk counted at the wrist and in the pocket produces different totals, and a user carrying both generates overlapping samples for a single real event. Summing without checking provenance double counts, which is the deduplication problem in its most common form.
Second, device being nil is itself information. A weight sample with no device is a person typing a number. A weight sample with a device is a connected scale. Those two are not equally trustworthy and should not feed a trend line on equal terms.
What this means when most users have only the phone
Health-wearable ownership runs between 13% and 46% depending on the market, which makes the phone-only user the majority case rather than the fallback.
Those figures come from national surveys and regulators rather than vendor estimates, and we keep the regional breakdown with definitions and sources, because wearable ownership numbers vary wildly depending on whether the survey counts fitness bands, smartwatches, or anything worn on a wrist.
The design consequence is worth stating plainly, because it inverts how most health features get scoped. Teams tend to build for the fully-equipped user and then treat the phone-only user as a degraded state to handle later. If most of your users are phone-only, that is backwards: you have designed the exception and left the common case as an afterthought.
The alternative is to work out what the motion-derived set actually supports on its own. Steps, distance, flights, and the mobility metrics carry more than they look like they do, particularly over time. Consistency of daily activity, changes in walking speed, shifts in when a person moves during the day, and gait quality trends are all derivable from a phone in a pocket, and all of them are behavioural signals rather than physiological ones.
That distinction is the useful one. A wearable measures your body. A phone measures your behaviour. Behaviour turns out to carry a great deal of health signal, which is the argument behind digital phenotyping and the reason a phone-only product is a real product rather than a compromised one.
The checklist before you scope a feature
For any HealthKit type your feature depends on, answer three questions before the estimate:
- What hardware produces it? Phone motion sensors, Watch, third-party device, or a person typing.
- What fraction of your users will have it? For Watch-derived types, assume a minority unless your audience is unusual.
- What happens when it is missing? Not as an error state, as the normal path for most users.
If a feature fails all three, it is not an integration task, it is a hardware requirement you are placing on your users without saying so. That is a legitimate product decision, and it should be made deliberately rather than discovered in a bug report three weeks after launch.
For the Android side of the same question, the equivalent breakdown is in HealthKit vs Health Connect, and for sleep specifically, what a phone can and cannot detect.
Choosing to serve those users anyway moves the work from reading a platform to estimating from what it does provide, which is a different kind of project with a different cost. We set out that arithmetic on our own build in build versus buy.
References
- Apple. HealthKit framework documentation. https://developer.apple.com/documentation/healthkit
- Apple. HKQuantityTypeIdentifier: quantity type identifiers, including mobility and walking metrics. https://developer.apple.com/documentation/healthkit/hkquantitytypeidentifier
- Apple. HKDevice: describing the hardware that produced a sample. https://developer.apple.com/documentation/healthkit/hkdevice
- Apple. HKSourceRevision: identifying the app or system that wrote a sample. https://developer.apple.com/documentation/healthkit/hksourcerevision
- Apple. Authorization and privacy in HealthKit, including the asymmetry between read and write permission visibility. https://developer.apple.com/documentation/healthkit/authorizing_access_to_health_data