Use HealthKit to enable your iOS and watchOS apps to work with the Apple Health app.

All subtopics
Posts under Health and Fitness topic

Post

Replies

Boosts

Views

Activity

怎样读取健康记录心理状态的情境,并将自己APP的数据传入进去
读取是不是解析 metadata 的对应键来获取值对吧~但我看了相关开发文档好像没找到这个的键是什么~于是也没法写入到对应的,现在只能自定义键来进行写入 但是这样写入后无法显示在心情下方的影响因素后面~ 这个 key 是没公开的吗还是说我方法弄错了~请各位大大指教
2
0
101
May ’25
Healthkit - Oura Sync Issue
We are working on the health related application and use apple health kit to sync the data from different devices like watches or ring. We are targeting oura ring to get sleep and other parameters data. We are able to sync the data from oura for all other parameters (like pulse, respiratory rate, blood pressure, etc..) other than sleep. Surprisingly, sleep data that comes through other devices is syncing as expected from the health kit. We are even getting the data which is added manually in health kit. The only sleep data not syncing is from oura. Can we get a document or any kind of help to sync the data from oura in to our application using health kit?
0
0
97
May ’25
Statistics collection query first result returned is wrong
I'm reading hourly statistics from HealthKit using executeStatisticsCollectionQuery (code below). Expectation What I expect is to get back the list with one row per hour, where each hours has the same cumulative sum value. Actual result In results, first hour always contains less calories than next hours, which all have the same value. Example: Start: 2025-06-02T00:00:00+03:00, anchor: 2025-06-02T00:00:00+03:00, end: 2025-06-02T12:00:00+03:00 🟡 2025-06-02T00:00:00+03:00 Optional(50.3986 kcal) 🟡 2025-06-02T01:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T02:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T03:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T04:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T05:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T06:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T07:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T08:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T09:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T10:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T11:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T12:00:00+03:00 Optional(14.0224 kcal) As you can see, here we have 2025-06-02T00:00:00+03:00 Optional(50.3986 kcal) Now, if I add one more hour to the request (from beginning of time window), the same hour has proper calories count, while newly added hour, has wrong value): 2025-06-01T23:00:00+03:00, anchor: 2025-06-01T23:00:00+03:00, end: 2025-06-02T12:00:00+03:00. 🟡 2025-06-01T23:00:00+03:00 Optional(50.3986 kcal) 🟡 2025-06-02T00:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T01:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T02:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T03:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T04:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T05:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T06:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T07:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T08:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T09:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T10:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T11:00:00+03:00 Optional(64.421 kcal) 🟡 2025-06-02T12:00:00+03:00 Optional(14.0224 kcal) And now first hour of the day, magically has more calories burned: 2025-06-02T00:00:00+03:00 Optional(64.421 kcal) I suspect similar things happen with other quantity types, but haven't yet found a way to reproduce it. Am I doing something wrong or is it a bug in HealthKit? Code let anchorDate = startDate let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: [.strictStartDate]) healthStore.executeStatisticsCollectionQuery( quantityType: .basalEnergyBurned, quantitySamplePredicate: predicate, options: [.separateBySource, .cumulativeSum], anchorDate: anchorDate, intervalComponents: DateComponents(hour: 1), initialResultsHandler: { statistics, error in if let error = error { log(.error, "Error retrieving steps: \(error.localizedDescription)") continuation.resume(throwing: SpikeException("Error retrieving steps: \(error.localizedDescription)")) return } if let statistics { let f = ISO8601DateFormatter() f.timeZone = TimeZone.current for s in statistics { log(.debug, "\(f.string(from: s.startDate)) \(s.sumQuantity())") } } continuation.resume(returning: statistics ?? []) } )
2
0
114
Jul ’25
Real-Time WatchConnectivity Sync Not Working Between iPhone and Apple Watch
Hi everyone, I'm building a health-focused iOS and watchOS app that uses WatchConnectivity to sync real-time heart rate and core body temperature data from iPhone to Apple Watch. While the HealthKit integration works correctly on the iPhone side, I'm facing persistent issues with WatchConnectivity — the data either doesn't arrive on the Watch, or session(_:didReceiveMessage:) never gets triggered. Here's the setup: On iPhone: Using WCSession.default.sendMessage(_:replyHandler:errorHandler:) to send real-time values every few seconds. On Apple Watch: Implemented WCSessionDelegate, and session(_:didReceiveMessage:) is supposed to update the UI. Both apps have WCSession.isSupported() checks, activate the session, and assign delegates correctly. The session state shows isPaired = true and isWatchAppInstalled = true. Bluetooth and Wi-Fi are on, both devices are unlocked and nearby. Despite all this, the Watch never receives messages in real-time. Sometimes, data comes through in bulk much later or not at all. I've double-checked Info.plist configurations and made sure background modes include "Uses Bluetooth LE accessories" and "Background fetch" where appropriate. I would really appreciate guidance on: Best practices for reliable, low-latency message delivery with WatchConnectivity. Debugging steps or sample code to validate message transmission and reception. Any pitfalls related to UI updates from the delegate method. Happy to share further details. Thanks in advance!
1
0
268
Jun ’25
Guideline 1.4.1 - Safety - Physical Harm
Hello everyone, my app is designed to help people sleep. It has been rejected multiple times due to issues with version 1.4.1 during the submission process. However, the app simply evaluates users’ insomnia and anxiety status based on their responses to questions and provides some relaxation methods. It does not involve any medical-related content. The reviewer provided screenshots of the assessment results page and some relaxation techniques. How should I handle this issue?
0
0
92
Jun ’25
Guideline 1.4.1 - Safety - Physical Harm
Hello everyone, my app is designed to help people sleep. It has been rejected multiple times due to issues with version 1.4.1 during the submission process. However, the app simply evaluates users’ insomnia and anxiety status based on their responses to questions and provides some relaxation methods. It does not involve any medical-related content. The reviewer provided screenshots of the assessment results page and some relaxation techniques. How should I handle this issue?
2
0
190
Jun ’25
HealthKit - HKWorkoutRouteBuilder never returns from insert when created from newly added iOS HKLiveWorkoutBuilder API on Simulator
Has anyone had success using the HKWorkoutRouteBuilder in conjunction with the new iOS support for HKLiveWorkoutBuilder? I was running my watchOS code that worked now brought over to iOS and when I call insertRouteData the function never returns. This happens for both the legacy and closure based block patterns. private var workoutSession: HKWorkoutSession? private var workoutBuilder: HKLiveWorkoutBuilder? private var serviceSession: CLServiceSession? private var workoutRouteBuilder: HKWorkoutRouteBuilder? private func startRouteBuilder() { Task { @MainActor in self.serviceSession = CLServiceSession(authorization: .whenInUse) self.workoutRouteBuilder = self.workoutBuilder?.seriesBuilder(for: .workoutRoute()) as? HKWorkoutRouteBuilder self.locationUpdateTask = Task { do { for try await update in CLLocationUpdate.liveUpdates(.fitness) { if let location = update.location { self.logger.notice(#function, metadata: [ "location": .stringConvertible(location) ]) try await self.workoutRouteBuilder?.insertRouteData([location]) self.logger.notice("Added location") } } } catch { self.logger.error(#function, metadata: [ "error": .stringConvertible(error.localizedDescription) ]) } } } } I did also try CLLocationManager API with delegate which is what my current watch code uses (a bit old). Same issue. Here is what I've found so far: If the workout session is not running, and if the builder hasn't started collection yet, inserting route data works just fine I've tried different swift language modes, flipped from main actor to non isolated project settings (Xcode 26) Modified Apple's sample code and added location route building to that and reproduced the error, modified sample attached to feedback This issue was identified against Xcode 26 beta 2 and iPhone 16 Pro simulator. Works as expected on my iPhone 13 Pro beta 2. FB18603581 - HealthKit: HKWorkoutRouteBuilder insert call within CLLocationUpdate task never returns
0
0
198
Jul ’25
Some swimming activities are not fetched by combined predicate
I'm using following filters to fetch swimming activities from HealthKit. For some users it fetches all workouts (pool && open water) but for other it skips some open water activities. See screenshot, all those swimming activities are not fetched by following code. let startDate = Calendar.current.date(byAdding: .month, value: -1, to: Date())! let endDate = Date() let swimmingPredicate = HKQuery.predicateForWorkouts(with: .swimming) let timePredicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: .strictStartDate) let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [swimmingPredicate, timePredicate]) let query = HKSampleQuery(sampleType: .workoutType(), predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: [.init(keyPath: \HKSample.startDate, ascending: false)], resultsHandler: { [weak self] query, samples, error in ... Could someone help with ideads what is missing in this case?
0
0
71
Jul ’25
HKLiveWorkoutBuilder get wrong calorie data for iOS 26
In iOS 26, HKLiveWorkoutBuilder is supported, which we can use like HKWorkoutSession in watchOS - this is very exciting. However, it currently seems to have a bug in calculating calories. I tested it in my app, and for nearly 6 minutes with an average heart rate of 134, it only calculated 8 calories consumed (80 calories per hour), including basal consumption, which is obviously incorrect. (I used Powerboats Pro 2 connected to my phone, which includes heart rate data, and HKLiveWorkoutBuilder correctly collected the heart rate, which is great.) I think my code is correct. func workoutBuilder(_ workoutBuilder: HKLiveWorkoutBuilder, didCollectDataOf collectedTypes: Set<HKSampleType>) { for type in collectedTypes { guard let quantityType = type as? HKQuantityType else { return // Nothing to do. } let statistics = workoutBuilder.statistics(for: quantityType) if let statistics = statistics { switch statistics.quantityType { case HKQuantityType.quantityType(forIdentifier: .heartRate): /// - Tag: SetLabel let heartRateUnit = HKUnit.count().unitDivided(by: HKUnit.minute()) let value = statistics.mostRecentQuantity()?.doubleValue(for: heartRateUnit) let roundedValue = Double( round( 1 * value! ) / 1 ) if let avg = statistics.averageQuantity()?.doubleValue(for: heartRateUnit) { self.avgHeartRate = avg } self.delegate?.didUpdateHeartBeat(self, heartBeat: Int(roundedValue)) case HKQuantityType.quantityType(forIdentifier: .activeEnergyBurned): let energyUnit = HKUnit.kilocalorie() let value = statistics.sumQuantity()?.doubleValue(for: energyUnit) self.totalActiveEnergyBurned = Double(value!) print("didUpdate totalActiveEnergyBurned: \(self.totalActiveEnergyBurned)") self.delegate?.didUpdateEnergyBurned(self, totalEnergy: self.totalActiveEnergyBurned + self.totalBasalEneryBurned) return case HKQuantityType.quantityType(forIdentifier: .basalEnergyBurned): let energyUnit = HKUnit.kilocalorie() let value = statistics.sumQuantity()?.doubleValue(for: energyUnit) self.totalBasalEneryBurned = Double(value!) print("didUpdate totalBasalEneryBurned: \(self.totalBasalEneryBurned)") self.delegate?.didUpdateEnergyBurned(self, totalEnergy: self.totalActiveEnergyBurned + self.totalBasalEneryBurned) return default: print("unhandled quantityType=\(statistics.quantityType) when processing statistics") return } } I think I've found the source of the problem: let workoutConfiguration = HKWorkoutConfiguration() workoutConfiguration.activityType = .traditionalStrengthTraining //walking, running is ok workoutConfiguration.locationType = .outdoor When I set the activityType to walking or running, the calorie results are correct, showing several hundred calories per hour. However, when activityType is set to traditionalStrengthTraining or jumprope, the calculations are incorrect. PS: I'm currently using Xcode 26 beta3 and iOS 26 beta3. Hope this issue can be resolved. Thanks.
1
0
159
Jul ’25
A Discussion on Marketing Sensitive Apps & Navigating App Review with a Privacy-First Approach
Hello everyone, Ujjwal here, founder and CEO of a new iOS app in the mental wellness space. Our mission is to provide accessible, AI-driven support for individuals dealing with anxiety, depression, and loneliness. From the very beginning, this has presented us with a unique and critical challenge: How do we effectively market an app to reach those who need it most, while upholding the absolute highest standards of user privacy? We've built our app, ThunDroid, with a "privacy-by-design" philosophy. We leverage on-device processing for our core AI features, utilize end-to-end encryption, and have proudly integrated 'Sign in with Apple' to maximize user anonymity. We believe these are not just features, but ethical obligations to our users, especially given the nature of the data they trust us with. The challenge, however, arises in marketing. This leads us to focus on mission-driven, organic marketing, but it's a slower path to reaching users who might be in immediate need of support. This brings me to my question for this knowledgeable community. What best practices or creative strategies have you found effective for marketing applications? I appreciate any insights or experiences you're willing to share as we continue to grow ThunDroid responsibly. Thank you for your time and consideration. App Store link: (would love to hear your reviews) [https://apps.apple.com/in/app/thundroid-ai-human-companion/id6746182736)
0
0
98
Jul ’25
How to accurately query HKWorkout segment data
Hello, In my application, I need to obtain precise workout segment data from HKWorkout in order to calculate per-kilometer metrics such as heart rate and pace. My current approach is: 1.Use HKWorkout to fetch the associated HKWorkoutEvents. 2.Take the end time of one event as the start time of the next event to derive per-kilometer segment ranges. The issue I’m facing: •If a user sets Apple Watch to notify every 5 kilometers, then at 5 km, 10 km, 15 km, etc., I see overlapping event times. •From the HKWorkoutEvents data alone, I cannot distinguish between events that represent “per-kilometer splits” and those that represent “5-kilometer notifications.” •As a result, my per-kilometer heart rate and pace calculations can be inaccurate. My question is: Is there a recommended way to reliably differentiate per-kilometer splits from custom distance notifications and ensure accurate segment data retrieval? For example, should I instead reconstruct segments using HKWorkoutRoute and distance samples, rather than relying on HKWorkoutEvents? STEPS TO REPRODUCE 1.On Apple Watch, start an Outdoor Run using the Workout app. 2.In workout notifications, set distance alerts to every 5 kilometers. 3.During the run, when reaching 5 km, 10 km, 15 km, etc., the watch triggers notifications. 4.Query the corresponding HKWorkout from HealthKit and inspect its HKWorkoutEvents. 5.Notice that some event start times are duplicated, and it is unclear which events represent “per-kilometer splits” and which represent “5-kilometer notifications.” Expected Result: Be able to differentiate between per-kilometer splits and custom distance alerts, so that heart rate and pace per kilometer can be calculated accurately. Actual Result: The HKWorkoutEvents data contains duplicated event times without a way to distinguish event types, leading to inaccurate per-kilometer statistics.
3
0
168
Oct ’25
Possible to bring back "Time in Bed" iOS feature?
I have an iPhone 11 Pro Max running iOS 26. But since iOS 18, Apple decided to remove the "Time in Bed" feature[1][2]. Is it possible to develop an app that, effectively, "brings back" this feature? It doesn't have to be that accurate. Just a gauge is fine. As a starter I would like to track the time the phone was in Sleep mode (regardless whether the phone is being used). I have a minimal programming background but have not developed an iOS app before so any help would be appreciated. I found out about HealthKit[3] which lets me access (edit?) Health data, but I don't know where to go from there. [1] https://www.reddit.com/r/iOSBeta/comments/1em8bl6/ios_181_db1_time_in_bed_via_iphone_feature_removed [2] https://www.reddit.com/r/ios/comments/1fkjat4/apple_removed_the_iphoneonly_sleep_tracking [3] https://developer.apple.com/documentation/healthkit
1
0
612
Oct ’25
Feature Request: Expand HealthKit Body Composition Data Types to Support Smart Body Scanning Scales
Summary: Expanding HealthKit to support the full spectrum of smart scale metrics will allow Apple Health to remain the central hub for health data, align with user expectations, and future-proof the framework as body composition analysis evolves. Description: With the growing adoption of smart body composition scales (e.g. segmental impedance scanners, multi-frequency analyzers, and body pods), users are generating a wide variety of clinically relevant metrics that currently cannot be stored natively in HealthKit. At present, HealthKit supports a core set of body composition values (Body Mass, BMI, Body Fat %, Lean Mass, Height, Waist Circumference). While useful, these do not capture the full picture modern devices provide, leading to fragmentation: • Users can see dozens of metrics in the device app, but only a handful flow into Health. • Developers must resort to metadata fields, which are inconsistent across apps and not accessible in Apple’s Health app UI. This gap undermines HealthKit’s role as a central, standardized health record. ⸻ Proposed Additions: Expand HealthKit HKQuantityTypeIdentifier to include additional body composition and derived measurements commonly reported by smart scales: Core Body Composition • Visceral fat percentage / rating • Skeletal muscle mass • Segmental muscle mass (arms, legs, trunk) • Segmental fat mass (arms, legs, trunk) • Bone mineral mass • Total body water % / hydration Derived Health Metrics • Muscle-to-fat ratio • Phase angle (bioelectrical impedance) • Metabolic age • Basal metabolic rate (BMR) ⸻ Rationale: • User benefit: Health app would show a more complete health profile, not just weight and fat %. • Developer benefit: Creates standardized identifiers, eliminating the need for proprietary storage in metadata. • Industry alignment: Many leading health devices already provide these metrics; users expect them to sync into Health. • Future-proofing: As body scanning scales proliferate, HealthKit can remain the trusted central repository rather than ceding ground to siloed vendor apps. ⸻ Suggested Implementation: • Introduce new HKQuantityTypeIdentifier values for each metric. • Permit segmental values to be represented as discrete samples with metadata for body region. • Ensure values can be written by apps/devices and surfaced in Health app UI, just like existing body composition data.
1
0
167
Oct ’25
HKObserverQuery and BackgroundDelivery Are Highly Unstable on watchOS 26
We are developing a health app that relies on HKObserverQuery and BackgroundDelivery to monitor Heart Rate data. On watchOS 10.6 and 11.6 , these data updates are typically delivered reliably every 8–12 minutes, occasionally exceeding 12 minutes, but generally not longer than 15 minutes. This frequency has been sufficient for the real-time data requirements of our app. However, after adapting our app to watchOS 26, we noticed that HKObserverQuery triggers much less frequently, with longer and very inconsistent intervals. This issue has had a major impact on our product: data collection for essential features is unreliable, resulting in a greatly diminished user experience on watchOS 26 and making the app essentially useless from the user’s perspective. Observed Behavior: HKObserverQuery and BackgroundDelivery are extremely unstable, with trigger intervals frequently exceeding 15 minutes, and sometimes even 20 minutes. When the user is sedentary, intervals become even longer; there are cases where no heart rate or active energy updates are delivered for 30 minutes, or even over 1 hour. Request for Support and Guidance: Have there been any changes to the HKObserverQuery background delivery mechanism on watchOS 26, specifically for Heart Rate and Active Energy data? If these changes are intentional system optimizations, could you provide guidance or recommended practices to ensure our app can reliably retrieve updates and maintain a smooth experience for users? Thank you for your support.
3
0
438
Jan ’26
Unable to receive HealthKit updates when app is force-quit — need clarification on background delivery limits
Hello, I’m developing a HealthKit-based fitness app in React Native that observes step count changes and uploads the latest totals to a remote server. I’m currently using HKObserverQuery with background delivery enabled (enableBackgroundDelivery(for:frequency:.immediate)), and the behavior works correctly while the app is running in the background or foreground. Whenever new step data is written to HealthKit, the app wakes up, reads the latest data, and sends it to my HTTPS endpoint using URLSession.shared.dataTask inside the observer callback. However, I’ve noticed the following issue: 1. If the user swipes up (force-quits) the app from the app switcher, the observer queries stop firing entirely. 2. In this state, even though HealthKit continues collecting step data from the device or Apple Watch, my app no longer receives those background deliveries until the user opens the app again. What I would like to achieve is: When the app is terminated (swiped up), and there are new step count updates in HealthKit, my app should still be able to receive those updates or be relaunched to handle them — similar to how some health companion apps continue syncing data and sending notifications even after being force-quit. So I have a few questions: Is this limitation expected — i.e., does iOS intentionally block HKObserverQuery background deliveries after a user force-quits the app? 2. Are there any special entitlements, background modes, or Apple-approved mechanisms that allow a health or medical app to continue receiving HealthKit changes even after a force-quit? 3. If not, what is the recommended architecture for apps that need to process HealthKit data continuously and send it to a backend server? For example, should such apps rely on server-side push notifications or CloudKit sync once the user reopens the app? My current goal is to ensure step count changes are uploaded reliably even if the app is killed, but I want to stay within the system’s supported behaviors and privacy constraints. Any clarification or guidance from Apple engineers or others who have implemented continuous HealthKit sync (like companion or medical apps) would be greatly appreciated. Thank you.
1
0
165
Oct ’25
HealthKit in React Native + Expo Dev Client: no authorization prompt (and no data)
Hi everyone, I’m building a health app with React Native using Expo Dev Client on a real iPhone. I need to read Apple Health (HealthKit) data, but the authorization sheet never appears—so the app never gets permissions and all queries return nothing. What I’ve already done Enabled HealthKit capability for the iOS target. Added NSHealthShareUsageDescription and NSHealthUpdateUsageDescription to Info.plist. Using a custom dev build (not Expo Go). Tested fresh installs (deleted the app), rebooted device, and checked Settings → Privacy & Security → Health/Motion & Fitness. Tried both packages: react-native-health and @kingstinct/react-native-healthkit. Same behavior: no permission dialog at first use. Ask Is there a known reason why the HealthKit permission sheet would not show on modern iOS when called from a React Native bridge (with Expo Dev Client)? Are there any extra entitlements, signing, or config-plugin steps required beyond HealthKit capability + Info.plist? If you’re successfully fetching Apple Health data from React Native on recent iOS, could you share the exact steps that made the permission sheet appear and data flow (Expo config/plugin used, Xcode capability setup, profile/team settings, build type, bundle ID nuances, any Health app reset steps, etc.)? This would help me and others hitting the same “authorized call but no prompt/no data” issue. Thank you!
1
0
279
Oct ’25
Enabling Cycling Power Read from Garmin Connect To Health
I am working on a cycling fitness app and I want to read the cycling power recorded using my Garmin edge from the Garmin Connect App. Currently the data is not transferred to the Health/Fitness Apps. Ideally it would be good to be able to query the power samples similar to the heart rate samples, but even the average power would suffice, as I could then calculate the Kilojoules.
1
0
178
Nov ’25
Can 3 party apps obtain Intervals information created using WorkoutKit?
I am developing a running training app that coaches can use to create interval workout plans. I can use HKWorkout to get information about Splits similar to that in Fitness app, but I can't get information about Intervals. My idea is to show interval details when users view their completed custom interval workout plans. Can I use Healthkit (or another feasible method) to get the actual distance or time of exercise in intervals workout ? (I know the workoutPlan property, but it doesn't reflect the segments of a real interval training workout.) Any insights or suggestions would be greatly appreciated! Thanks in advance!
0
0
196
Dec ’25