feat: add queryActivitySummaries - #358
Conversation
🦋 Changeset detectedLatest commit: e193d7a The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
Pull request overview
This PR adds first-class support for querying Apple HealthKit Activity Ring daily rollups by introducing a new Nitro-backed ActivitySummaryModule and exposing a queryActivitySummaries(startDate, endDate) API from the JS surface of react-native-healthkit.
Changes:
- Introduces
ActivitySummaryTS type plus a new Nitro specActivitySummaryModule.nitro.tsfor queryingHKActivitySummaryQueryresults. - Wires the new module through Nitro registration (
nitro.json), JS module creation (modules.ts), and platform exports (healthkit.ts/healthkit.ios.ts). - Adds a changeset to publish the new API as a minor version bump.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/react-native-healthkit/src/types/index.ts | Re-exports the new ActivitySummary type from the types barrel. |
| packages/react-native-healthkit/src/types/ActivitySummary.ts | Defines the JS/TS shape for per-day activity ring values + goals. |
| packages/react-native-healthkit/src/specs/ActivitySummaryModule.nitro.ts | Adds the Nitro module interface for queryActivitySummaries. |
| packages/react-native-healthkit/src/modules.ts | Registers ActivitySummaryModule as a Nitro hybrid object factory. |
| packages/react-native-healthkit/src/healthkit.ts | Exposes queryActivitySummaries with a non-iOS unavailable fallback and adds it to the default export object. |
| packages/react-native-healthkit/src/healthkit.ios.ts | Binds and re-exports queryActivitySummaries on iOS via bindRetypedMethod. |
| packages/react-native-healthkit/nitro.json | Adds Swift module autolinking registration for ActivitySummaryModule. |
| packages/react-native-healthkit/ios/ActivitySummaryModule.swift | Implements HKActivitySummaryQuery execution and serialization to the Nitro-generated ActivitySummary type. |
| .changeset/itchy-pandas-applaud.md | Declares a minor release for the new API. |
| return Promise.async { | ||
| let calendar = Calendar.current | ||
|
|
||
| var startComponents = calendar.dateComponents( | ||
| [.day, .month, .year, .era], from: startDate) | ||
| var endComponents = calendar.dateComponents( | ||
| [.day, .month, .year, .era], from: endDate) |
| let query = HKActivitySummaryQuery(predicate: predicate) { _, summaries, error in | ||
| if let error = error { | ||
| continuation.resume(throwing: error) | ||
| } else { | ||
| continuation.resume(returning: summaries ?? []) | ||
| } | ||
| } |
| return summaries.map { summary in | ||
| let components = summary.dateComponents(for: calendar) | ||
| return ActivitySummary( | ||
| dateYear: Double(components.year ?? 0), | ||
| dateMonth: Double(components.month ?? 0), | ||
| dateDay: Double(components.day ?? 0), | ||
| activeEnergyBurned: summary.activeEnergyBurned.doubleValue(for: .kilocalorie()), | ||
| activeEnergyBurnedGoal: summary.activeEnergyBurnedGoal.doubleValue(for: .kilocalorie()), | ||
| appleExerciseTime: summary.appleExerciseTime.doubleValue(for: .minute()), | ||
| appleExerciseTimeGoal: summary.appleExerciseTimeGoal.doubleValue(for: .minute()), | ||
| appleStandHours: summary.appleStandHours.doubleValue(for: .count()), | ||
| appleStandHoursGoal: summary.appleStandHoursGoal.doubleValue(for: .count()), | ||
| appleMoveTime: summary.appleMoveTime.doubleValue(for: .minute()), | ||
| appleMoveTimeGoal: summary.appleMoveTimeGoal.doubleValue(for: .minute()) | ||
| ) | ||
| } |
| queryActivitySummaries( | ||
| startDate: Date, | ||
| endDate: Date, | ||
| ): Promise<ActivitySummary[]> |
| const ActivitySummaryBindings = { | ||
| queryActivitySummaries: bindRetypedMethod< | ||
| typeof ActivitySummaries, | ||
| typeof ActivitySummaries.queryActivitySummaries, | ||
| Promise<ActivitySummary[]> | ||
| >(ActivitySummaries, ActivitySummaries.queryActivitySummaries), | ||
| } satisfies { | ||
| queryActivitySummaries: BoundMethod< | ||
| typeof ActivitySummaries.queryActivitySummaries, | ||
| Promise<ActivitySummary[]> | ||
| > | ||
| } |
|
@imikeyi03 Looks good! Could you have a look at the failing lints as well as the PR comments? Then I think we're ready to merge. |
Summary
Adds a minimal
queryActivitySummaries(startDate, endDate)API exposingHKActivitySummaryQuery— the per-day Apple activity-ring rollups (move/exercise/stand values and goals), which were previously unreachable from this library even thoughActivitySummaryTypeIdentifieris already supported for authorization.Closes #215.
API
Design notes:
dateYear/dateMonth/dateDay) rather than aDate, becauseHKActivitySummaryis keyed byDateComponents— converting to a timestamp would impose a timezone assumption on callers. The query inputs are reduced to day granularity in the user's current calendar, which is inherent toHKActivitySummaryQuery..calendaron bothDateComponents(the classicHKActivitySummaryQuerygotcha — without it the query silently returns nothing).ActivitySummaryModulemirroring the existing per-domain module structure (StateOfMindModulewas the exemplar): nitro spec +nitro.jsonautolinking registration + Swift impl +bindRetypedMethodbindings +UnavailableFnFromModulefallback on non-iOS platforms.Testing
bun codegen,bun typecheck,bun lint,bun run testall green locally.