Highlight
The Health app has supported medication tracking since iOS 15, but third-party apps could not read this data. Now the Medications API opens that door.
Core Content
Users have been recording medications in the Health app for four years. Scheduled doses, missed doses, backlogged entries, archived meds—all this data stayed locked inside Health. Third-party health apps that wanted to build experiences like “medication-symptom correlation,” “long-term adherence charts,” or “side effect reminders” had to ask users to re-enter everything, creating a fragmented experience.
iOS 26 opens that door. HealthKit adds a new set of Medications APIs across iOS, iPadOS, and visionOS (00:17). Third-party apps can now read the medication list users added in Health and every dose record, and connect them to symptoms, side effects, and medical concepts using clinical coding systems like RxNorm. Authorization is smoother too: when users add a new medication in Health, the system directly shows a toggle to “share with authorized apps”—no need for the app to request permission again (22:46).
Details
Two Core Data Objects
The new API revolves around two objects (02:16):
HKUserAnnotatedMedication: A specific medication the user added to Health, containingisArchived(whether archived/no longer taken),hasSchedule(whether a reminder schedule is set),nickname(user’s nickname, e.g., calling Amoxicillin “Antibiotics”), and a reference to anHKMedicationConcept(02:59).HKMedicationDoseEvent: A new type ofHKSamplerepresenting “one dose that should have or actually did occur”. Contains log status (taken / skipped / snoozed / no interaction), scheduled date and scheduled quantity, actual dose quantity, and a medication concept identifier that links it to a specific medication (04:32).
HKMedicationConcept itself is not a prescription record—it is the “conceptual meaning of a medication”—a cross-device stable identifier, a display text (e.g., “Amoxicillin Trihydrate 500mg Oral Tablet”), a general form (capsule / tablet / liquid), and a set of related codings (e.g., RxNorm code 308192) (03:38).
Requesting Authorization: Per-Object for Medications, Doses Follow Automatically
Medications are objects, not samples, so authorization uses the per-object path, with object type set to the new HKUserAnnotatedMedicationType (10:18):
HealthDataAccessRequest(
store: healthStore,
objectType: HKUserAnnotatedMedicationType(),
trigger: $triggerAuthorization
) { result in
// Handle authorization result
}
Key points:
objectTypeusesHKUserAnnotatedMedicationType(), telling the system to authorize at the object level. This presents a per-medication selection interface where users can decide individually whether to share each medication with the current app.triggeris a SwiftUI state binding; setting it totruebrings up the authorization sheet.- Once the user authorizes a medication, you do not need to separately request read permission for that medication’s dose events—dose events are automatically authorized (11:10).
If you also need to read sample types like “symptoms” (headache, nausea), use a separate request passing a list of sample types (11:23).
Querying Medication List: New Query Descriptor
let descriptor = HKUserAnnotatedMedicationQueryDescriptor()
let medications = try await descriptor.result(for: healthStore)
Key points:
HKUserAnnotatedMedicationQueryDescriptoris a newly introduced descriptor specifically for fetching medication lists (02:39).- Without a predicate or limit, it returns both active and archived medications (12:32).
- Supported predicates include two new predicates:
isArchivedandhasSchedule(08:07). - The app only sees medications the user has authorized; unauthorized ones won’t appear in results.
Querying Dose Events: Reuse HKSample Query System
Dose events are a new subtype of HKSample, so you can query them directly using the three existing query types: sample query, anchored object query, and observer query (08:29). In the demo, when querying “the most recent dose taken today,” a sample query descriptor was used with a compound predicate (filtering by medication concept, today’s date, and log status = taken), configured with sort + limit = 1 (13:22).
Chart Scenarios: Use Anchored Object Query for Real-Time Updates
For continuously refreshing views like “medication trend charts,” use anchored object query. Eric pointed out a few gotchas (18:21):
- Dose events can be backlogged to a past date;
- Editing once deletes the old sample before writing the new one;
- Reminders with no user interaction still leave a record.
When processing results, you must consume deleted objects first, then handle added samples—otherwise your data model will show phantom points. The anchored query’s Swift async interface continuously yields new batches, making it ideal for real-time charts (19:57).
Connecting Medications to Symptoms with RxNorm
HKMedicationConcept.relatedCodings contains a set of clinical codings (system + code), where the RxNorm system URL is http://www.nlm.nih.gov/research/umls/rxnorm (15:55). In the demo, Srishti prepared a static dictionary mapping “RxNorm code → side effect symptom list,” used the medication’s RxNorm code to look up which symptom options to display, let users record symptom intensity with emoji, and finally saved it as a HealthKit category sample (16:18).
”Zero-Friction Authorization” for New Medications
After an app has requested medication authorization, when the user adds another new medication in Health, the Health app directly shows a “share with XX app” toggle before saving—developers don’t need to request authorization again (22:46). The app will naturally see the new medication on its next query.
Key Takeaways
1. Treat Health App as the Medication Data Source, Stop Re-entering Data
Why it’s worth doing: Many health apps previously required users to re-enter medications, creating a fragmented experience with low adherence. Now you can read directly from Health—users add meds where they add meds, third-party apps focus on value-added experiences.
How to start: Add an “Import medications from Health” entry point in onboarding, call HealthDataAccessRequest + HKUserAnnotatedMedicationType() to let users select which medications to share.
2. Use RxNorm to Link Medications to Side Effect Knowledge Bases
Why it’s worth doing: Medication names may drift across devices and languages, but RxNorm codes are stable global identifiers. Once your side effects, drug interactions, and educational content are indexed on RxNorm, they can be reused across users and regions.
How to start: Filter HKMedicationConcept.relatedCodings for codes where the system is the RxNorm URL (http://www.nlm.nih.gov/research/umls/rxnorm), build a lookup table of “RxNorm code → side effect list,” and map against existing HealthKit category types (headache, nausea, etc.) to let users log intensity.
3. Use Anchored Object Query for “Adherence” Charts
Why it’s worth doing: Dose events update as a stream—old data gets modified, past dates get backfilled. Anchored query provides dual-track updates with “increments + deletion list,” making it the best match for chart scenarios—more efficient than observer + sample query (19:50).
How to start: In your chart view, start a Swift async anchored query. Pass nil for the first anchor, then for each yielded batch of results, apply deletes first then additions, updating the chart data source.
4. Design Separate Views for Skipped / Snoozed
Why it’s worth doing: Log status isn’t just “taken.” Treat skipped as “reminder didn’t work” and snoozed as a signal to “redesign reminder frequency,” and you can surface insights deeper than Health’s built-in UI.
How to start: Pull the past 30 days of non-taken records using the dose event’s log status predicate, aggregate by medication, and show users “missed dose hot spots.”
5. Turn “Auto-Authorize New Medications” into a Product Promise
Why it’s worth doing: Users hate repeatedly authorizing across apps. Health has built new medication sharing into a toggle after the first authorization—write this mechanism into your onboarding promise with “Remember to check share with me when adding new meds in Health”—and retention becomes steadier.
How to start: Add explanation copy on the success screen after first authorization, and ensure your main app query path guarantees “new meds appear automatically,” avoiding local cache that blocks new data.
Related Sessions
- Get started with HealthKit on visionOS — Introductory guide to extending HealthKit experiences to Apple Vision Pro.
- Meet workouts on iOS — Eric’s recommended sister session at the end, covering new workout capabilities on iOS.
- Enhance child safety with PermissionKit — Another example of a per-object style authorization flow.
- Dive into App Store server APIs for In-App Purchase — A reference point for server API evolution on another front.
- Discover Apple-Hosted Background Assets — Sets the stage for scenarios like health data that need background sync.
Comments
GitHub Issues · utterances