Skip to content

feat: query Apple HealthKit activity summaries - #397

Merged
robertherber merged 1 commit into
kingstinct:masterfrom
michaelyta:feat/query-activity-summary
Oct 9, 2026
Merged

robertherber merged 1 commit into
kingstinct:masterfrom
michaelyta:feat/query-activity-summary

Conversation

@michaelyta

@michaelyta michaelyta commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

This PR introduces the queryActivitySummary API, exposing HealthKit's HKActivitySummaryQuery. This allows consumers to read Apple Watch activity ring rollups and goals (active energy burned/goal, exercise time/goal, stand hours/goal, move time, and move mode) for single days or date ranges.

Closes #215.


API Reference

import { queryActivitySummary } from '@kingstinct/react-native-healthkit'

// Query all available summaries
const summaries = await queryActivitySummary()

// Or query for a specific date or date range
const summaries = await queryActivitySummary({
  date: {
    startDate: new Date('2026-10-01'),
    endDate: new Date('2026-10-08'),
  },
})

Return Type

interface ActivitySummary {
  dateComponents?: ActivitySummaryDateComponents
  activityMoveMode: ActivityMoveMode // 'activeEnergy' | 'appleMoveTime'
  activeEnergyBurned: QuantityType<EnergyUnit>
  activeEnergyBurnedGoal: QuantityType<EnergyUnit>
  appleExerciseTime: QuantityType<TimeUnit>
  appleExerciseTimeGoal: QuantityType<TimeUnit>
  appleStandHours: QuantityType<CountUnit>
  appleStandHoursGoal: QuantityType<CountUnit>
  appleMoveTime?: QuantityType<TimeUnit>
  appleMoveTimeGoal?: QuantityType<TimeUnit>
  isPaused?: boolean
}

Design of the Change

  1. Nitro Specification (CoreModule.nitro.ts) & Types:
    queryActivitySummary is added as an async method to CoreModule. Type definitions match HealthKit's HKActivitySummary structure and use the existing Nitro quantity wrappers (QuantityType<...>), keeping returned quantities strongly typed with their respective units (kilocalorie, minute, count).

  2. Native Swift Implementation (CoreModule.swift):
    HealthKit requires DateComponents with an assigned calendar to build activity summary predicates. I convert the JS input dates to Calendar.current date components with .year, .month, .day, .era.

    To construct the query predicate, HealthKit exposes different factory methods depending on whether both dates, one date, or no date bounds are provided (forActivitySummariesBetweenStart:end: crashes if given nil arguments). A clean Swift pattern-matching switch handles each variation:

    let predicate: NSPredicate? = switch (start, end) {
    case let (.some(start), .some(end)):
      HKQuery.predicate(forActivitySummariesBetweenStart: start, end: end)
    case let (.some(start), .none):
      HKQuery.predicateForActivitySummary(with: start)
    case let (.none, .some(end)):
      HKQuery.predicateForActivitySummary(with: end)
    default:
      nil
    }
  3. Serialization (Serializers.swift):
    HKActivitySummary is a composite object that does not conform to HKSample. A dedicated serializeActivitySummary serializer unwraps all goal and burned quantities using serializeQuantityTyped, converts dateComponents(for: Calendar.current), handles activityMoveMode enum mapping, and conditionally gates isPaused behind iOS 18 / Swift 6 availability checks.

  4. Multiplatform & Testing Stubs:
    Exposed in healthkit.ios.ts, stubbed with createUnavailableFn in healthkit.ts for non-iOS platforms, and mocked in test-setup.ts.


Testing & Verification

  • Unit tests: Added unit tests in queryActivitySummary.test.ts validating filter constructions, date components, and enum lookups.
  • Linter & Type checks: Verified with bun run typecheck, bun run lint, and bun run swiftlint.
  • Simulator & Example app:
    I verified the native bridge and UI flow inside the example app. Note that the standalone iOS Simulator does not calculate or synthesize daily HKActivitySummary rollups (even when manually inserting raw active energy or workout samples in the Health app, HKActivitySummaryQuery returns an empty array on simulator environments). To verify the bridge, serialization, and React Native UI rendering end-to-end on simulator, I temporarily mocked an HKActivitySummary instance in Swift and confirmed it rendered all values and units correctly.
  • Physical Device & Real Health Data:
    Because running the example app directly on a physical device hit provisioning profile/signing constraints with its bundle identifier, I packaged this patch and locally linked it into a fitness app I'm working on running on a physical iPhone. Calling queryActivitySummary() successfully queried and returned real Apple Watch Activity Rings data (energy burned, exercise time, stand hours, and goals).

@changeset-bot

changeset-bot Bot commented Oct 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c21a9e9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@kingstinct/react-native-healthkit Minor
@react-native-healthkit/core Minor
@react-native-healthkit/health-records Minor

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

@michaelyta
michaelyta marked this pull request as ready for review October 9, 2026 01:12
@pkg-pr-new

pkg-pr-new Bot commented Oct 9, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/kingstinct/react-native-healthkit/@react-native-healthkit/core@397
npm i https://pkg.pr.new/kingstinct/react-native-healthkit/@react-native-healthkit/health-records@397
npm i https://pkg.pr.new/kingstinct/react-native-healthkit/@kingstinct/react-native-healthkit@397

commit: c21a9e9

@robertherber
robertherber enabled auto-merge October 9, 2026 13:24
@robertherber
robertherber merged commit 6d3943a into kingstinct:master Oct 9, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: add support for querying Activity Summary objects from HealthKit

2 participants