Add HealthKit sensors to iOS app#4923
Conversation
There was a problem hiding this comment.
Pull request overview
Adds optional Apple Health (HealthKit) backed sensors to the iOS app so selected health metrics can be exposed via the existing Home Assistant sensor webhook flow.
Changes:
- Introduces a new
HealthKitSensorprovider with caching and per-metric enablement. - Adds a persisted master toggle + cache storage in
SettingsStore, and wires a new “Apple Health” section into the Sensors settings UI. - Adds HealthKit entitlement + usage description strings, plus unit tests for sensor collection/encoding and settings wiring.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| Tests/Shared/Sensors/HealthKitSensor.test.swift | Adds unit tests for HealthKit sensor behavior (availability, caching, enable/disable). |
| Tests/App/Settings/SensorListViewModelHealthKitTests.swift | Adds unit tests for HealthKit toggle behavior in the sensors settings view model. |
| Sources/Shared/Settings/SettingsStore.swift | Persists HealthKit sensors master enable state, “ever enabled” flag, and cached values. |
| Sources/Shared/Resources/Swiftgen/Strings.swift | Adds SwiftGen accessors for new HealthKit-related localized strings. |
| Sources/Shared/Environment/Environment.swift | Adds HealthKit dependency wrapper + registers the new HealthKit sensor provider. |
| Sources/Shared/API/Webhook/Sensors/HealthKitSensor.swift | Implements the HealthKit-backed sensor provider and cache model types. |
| Sources/App/Settings/Sensors/List/SensorListViewModel.swift | Adds HealthKit status state, toggle handling, and hides HealthKit sensors when master toggle is off. |
| Sources/App/Settings/Sensors/List/SensorListView.swift | Adds an Apple Health section with master toggle + status display to the Sensors settings UI. |
| Sources/App/Resources/Info.plist | Adds NSHealthShareUsageDescription. |
| Sources/App/Resources/en.lproj/Localizable.strings | Adds localized strings for the Sensors settings Apple Health section. |
| Sources/App/Resources/en.lproj/InfoPlist.strings | Adds localized NSHealthShareUsageDescription. |
| HomeAssistant.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved | Adds a new SPM lockfile under the .xcodeproj workspace. |
| HomeAssistant.xcodeproj/project.pbxproj | Adds new source/test files to the project and enables the HealthKit capability. |
| Configuration/Entitlements/App-ios.entitlements | Enables the HealthKit entitlement for the iOS app target. |
|
Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍 |
| func requestHealthAuthorization() -> Promise<Void> { | ||
| Current.healthKit.requestReadAuthorization().get { [weak self] in | ||
| self?.healthKitStatus = Current.healthKit.authorizationStatus() | ||
| } | ||
| } |
| public var authorizationStatus: () -> HealthKitSensor.AuthorizationStatus = { | ||
| Current.healthKit.isAvailable() ? .available : .unavailable | ||
| } |
| healthStore.requestAuthorization(toShare: Set<HKSampleType>(), read: types) { success, error in | ||
| if let error { | ||
| seal.reject(error) | ||
| } else if success { | ||
| seal.fulfill(()) | ||
| } else { | ||
| seal.reject(HealthKitSensor.HealthKitSensorError.authorizationFailed) | ||
| } |
| let sample = samples?.first as? HKQuantitySample | ||
| seal.fulfill(sample?.quantity.doubleValue(for: .init(from: "count/min"))) | ||
| } |
|
Please do not use AI to answer PR comments, if you/AI implemented it in a specific way, the implementation could be correct, I'm just making questions to evaluate the reasoning. |
|
Please provide screenshots of how the sensors in app, sensors in HA, and permission request look like. |
| Current.healthKit.isAvailable() ? .available : .unavailable | ||
| } | ||
|
|
||
| public var requestReadAuthorization: () -> Promise<Void> = { |
There was a problem hiding this comment.
Authorization request should not live in Environment, create a HealthKit service that handles health related requests.
| #endif | ||
| } | ||
|
|
||
| public var queryStepCount: (Date, Date) -> Promise<Int?> = { start, end in |
| #endif | ||
| } | ||
|
|
||
| public var queryLatestRestingHeartRate: (Date, Date) -> Promise<Double?> = { start, end in |
| } | ||
| } | ||
|
|
||
| public var healthKit = HealthKit() |
There was a problem hiding this comment.
It should only be available for iOS
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4923 +/- ##
=======================================
Coverage ? 50.14%
=======================================
Files ? 284
Lines ? 18147
Branches ? 0
=======================================
Hits ? 9099
Misses ? 9048
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Summary
Adds optional HealthKit-backed iOS sensors so selected health metrics can be exposed through the existing Home Assistant sensor webhook flow.
This includes:
Screenshots
N/A - this uses the existing Sensors settings list UI patterns and does not introduce a new custom screen.
Link to pull request in Documentation repository
Documentation: home-assistant/companion.home-assistant#1368
Any other notes
Validation: CI passed on the fork PR, including lint, unused-string checks, SwiftLint disable checks, and the test job: https://github.com/aero-oli/iOS/actions/runs/28614134149