The introduction of medications APIs in HealthKit represents a significant advancement for health-focused iOS applications. These APIs enable developers to create sophisticated medication tracking experiences across iOS, iPadOS, and visionOS platforms.
Core API Components
HKUserAnnotatedMedication
This object represents a specific medication with user customizations:
- isArchived: Boolean flag indicating if medication is no longer active
- hasSchedule: Indicates presence of reminder notifications
- nickname: User-friendly name for personalization
- medicationConcept: Reference to the actual medication details
HKMedicationConcept
Embodies the conceptual medication with clinical data:
- identifier: Unique identifier across devices and time
- displayText: Human-readable medication name
- generalForm: Physical form (capsule, tablet, liquid)
- relatedCodings: Clinical codes from standardized terminologies (RxNorm)
HKMedicationDoseEvent
Represents medication logging events as HKSample objects:
- medicationConceptIdentifier: Links to specific medication
- logStatus: Event status (taken, skipped, snoozed)
- doseQuantity: Amount actually taken
- scheduledQuantity: Amount that was scheduled
- scheduledDate: Original scheduled time
Query Implementation
Fetching Medications
Use the new query descriptor for medication retrieval:
// Basic medication query
let queryDescriptor = HKUserAnnotatedMedicationQueryDescriptor()
// With predicates for filtering
let archivedPredicate = HKQuery.predicateForUserAnnotatedMedications(isArchived: false)
let schedulePredicate = HKQuery.predicateForUserAnnotatedMedications(hasSchedule: true)
Dose Event Queries
Leverage existing HKSample query patterns:
- Sample queries for basic retrieval
- Anchored object queries for real-time updates
- Observer queries for background monitoring
Key predicates for dose events:
- Filter by specific medication
- Filter by log status
- Date range filtering
- Compound predicates for complex queries
Authorization Strategy
Per-Object Authorization
Medications use HealthKit's per-object authorization model:
// Request medication access
let medicationType = HKUserAnnotatedMedicationType()
healthStore.requestPerObjectReadAuthorization(for: medicationType) { success, error in
// Handle authorization result
}
Important notes:
- Authorization grants access to both medication and its dose events
- Users can selectively authorize individual medications
- New medications added in Health app automatically prompt for app authorization
Sample Type Authorization
For related health data (symptoms, side effects):
let sampleTypes: Set<HKSampleType> = [
HKCategoryType(.headache),
HKCategoryType(.nausea)
// Additional symptom types
]
healthStore.requestAuthorization(toShare: sampleTypes, read: sampleTypes) { success, error in
// Handle authorization
}
Advanced Implementation Patterns
Anchored Object Queries for Real-Time Updates
Essential for maintaining data consistency:
// Supply nil for anchor to start from beginning
let anchor = nil
// Configure query with predicates for medication and date window
// Use swift async interface for background execution
// Process results in handleResult function
Key considerations from the transcript:
- Handle deleted objects from query results
- Process dose events that may be logged for past dates
- Manage data that gets deleted and re-persisted during editing
- Account for scheduled reminders that were never interacted with
- Use Swift async interface for efficient background processing
Clinical Coding Integration
Leverage RxNorm for enhanced functionality:
let rxNormSystem = "http://www.nlm.nih.gov/research/umls/rxnorm"
func extractRxNormCodes(from medication: HKMedicationConcept) -> [String] {
return medication.relatedCodings
.filter { $0.system == rxNormSystem }
.map { $0.code }
}
Clinical coding applications:
- Associate medications with side effects
- Link to educational content
- Enable interoperability with health systems
- Facilitate medication categorization
Data Management Considerations
Handling Dose Event Complexity
Dose events require careful handling due to their interactive nature:
- Retroactive logging: Events may be saved for past dates
- Editing scenarios: Original events deleted and re-persisted
- Scheduled reminders: Events created for uninteracted notifications
- Status variations: taken, skipped, snoozed, or not interacted
Performance Optimization
- Use appropriate query limits for large datasets
- Implement background processing for data-intensive operations
- Cache frequently accessed medication concepts
- Batch process multiple dose events efficiently
User Experience Integration
Medication Detail Views
Create comprehensive medication interfaces:
- Display medication concept information
- Show recent dose history
- Integrate scheduling status
- Present user customizations (nicknames, notes)
Side Effect Tracking
Implement symptom correlation:
// Example: Associating medications with potential side effects
struct MedicationSideEffect {
let rxNormCode: String
let symptomTypes: [HKCategoryType]
let commonIntensities: [SymptomIntensity]
}
Chart and Analytics Views
Leverage anchored queries for dynamic visualizations:
- Real-time dose compliance tracking
- Historical medication adherence
- Side effect correlation analysis
- Multi-medication interaction insights
Security and Privacy
Data Protection
- Medications data inherits HealthKit's security model
- Per-object authorization provides granular control
- Automatic encryption in transit and at rest
- User maintains complete control over data sharing
Authorization Management
- Handle authorization gracefully when denied
- Provide clear explanations for data requests
- Respect user privacy preferences
- Implement fallback experiences for unauthorized data
Development Best Practices
Error Handling
Implement robust error management:
// Comprehensive error handling pattern
func fetchMedications() async throws -> [HKUserAnnotatedMedication] {
do {
let queryDescriptor = HKUserAnnotatedMedicationQueryDescriptor()
let results = try await queryDescriptor.result(for: healthStore)
return results
} catch {
// Log error appropriately
throw MedicationError.fetchFailed(underlying: error)
}
}
Testing Strategies
- Create comprehensive test medications in Health app
- Test various dose logging scenarios
- Validate authorization flow edge cases
- Verify anchored query behavior with data changes
Documentation and Maintenance
- Document clinical coding integrations clearly
- Maintain medication-to-symptom mappings
- Version control query predicate configurations
- Keep authorization flows updated with iOS changes
Conclusion
The HealthKit medications API provides a comprehensive foundation for medication management applications. Success depends on thoughtful implementation of authorization flows, robust data querying strategies, and careful attention to the complex nature of medication logging behaviors.
Top comments (1)
Use the new query descriptor for medication retrieval -
HKUserAnnotatedMedicationQueryDescriptor