Health & Fitness

RSS for tag

Explore the technical aspects of health and fitness features, including sensor data acquisition, health data processing, and integration with the HealthKit framework.

Health & Fitness Documentation

Posts under Health & Fitness subtopic

Post

Replies

Boosts

Views

Activity

HealthKit workout deletion does not remove Exercise Minutes and Active Energy generated during the session
I’m developing a watchOS application for Apple Watch Ultra 2 that continuously monitors heart rate during non-sporting activities, such as driving. The application uses: ● HKWorkoutSession ● HKLiveWorkoutBuilder ● HKAnchoredObjectQuery to retrieve heart rate samples I have observed that starting a workout session allows frequent heart rate measurements to continue even when the Apple Watch display becomes dimmed. However, this creates an unwanted side effect: although the user is not exercising, the session contributes to the Activity rings. In my tests, a workout recorded as type .other generated Exercise Minutes and Active Energy, even though the saved workout itself reported 0 active calories. The problem occurs when deleting the workout. After selecting Delete Workout & Data in the Health/Fitness interface: 1. The workout disappears from the workout history. 2. The Exercise Minutes generated during the session remain in HealthKit. 3. The Active Energy samples generated during the same interval also remain. 4. The corresponding Activity ring totals are not immediately corrected. I subsequently deleted the Exercise Minutes samples manually from the Health app. This corrected the numerical Exercise Minutes total. The Active Energy samples required separate handling. In some tests, the numerical values and the graphical representation of the Activity rings also appeared temporarily inconsistent. My questions are: 1. Is this the expected behavior of HealthKit when deleting a workout created using HKWorkoutSession and HKLiveWorkoutBuilder? 2. Why does Delete Workout & Data leave Exercise Minutes and Active Energy samples generated during the workout interval? 3. Are these samples considered independent system-generated measurements rather than data associated with the workout? 4. Is there a supported way to prevent a monitoring session from contributing to the Activity rings while still maintaining frequent heart rate acquisition in the background? My objective is to monitor physiological parameters during activities that are not exercise, without modifying the user’s fitness statistics. I would appreciate clarification about the intended behavior of these APIs and the recommended implementation approach.
2
0
79
1d
Health rejects CDA XML import on iOS 27.2 beta 4 — compatibility requirements? FB25204405
Hello, I’m investigating CDA XML compatibility with the Health app’s medical document import feature. Health rejects both custom CDA documents and an unchanged public HL7 CCD sample with a generic “No medical documents were found to import” error. Feedback Assistant report: FB25204405. Environment: iPhone 15 Pro Max iOS 27.2 beta 4 (24B5110a) Device language: Hebrew Region: Israel Steps to reproduce: Save a CDA XML document in Files. Open the document’s share sheet and select Health. Health opens but displays an error instead of a document preview or import confirmation. The exact Hebrew error is: “לא ניתן לייבא מסמכים רפואיים” “לא נמצאו מסמכים רפואיים לייבוא.” Approximate English translation: “Unable to Import Medical Documents” “No medical documents were found to import.” For comparison, I also tried the unchanged public HL7 CCD sample containing fictional patient data: https://github.com/HL7/CDA-core-2.0/blob/master/examples/sampleCCD.xml This sample produces the same error. I understand that being an HL7 sample does not necessarily mean it satisfies all of Health’s import requirements. My questions: Is standalone CDA XML import from Files into Health supported through this workflow? Are there specific CDA profiles, header fields, filename extensions, or packaging requirements needed for Health to recognize the document? Has anyone successfully imported a CDA document on this build, or identified a workaround? Is there a recommended way to distinguish a document validation failure from a file recognition or handoff failure? Testing so far has been limited to the Health app’s user interface. I have not tested the document through HKCDADocumentSample in a native app, and I have not established whether this is a regression from an earlier iOS version. I would appreciate guidance on the supported workflow or a public, fictional-data sample known to work with Health. Please do not share real patient records. Thank you.
1
1
131
2d
watchOS 27 Workout sessions record almost no heart rate samples (Series 10) - FB24834050
Filed as FB24834050. Still reproducible on watchOS 27.0.1 (24R365). Posting here in case an Apple engineer can help route it, and to see whether other developers are seeing the same behavior through HealthKit. Minimal reproduction (under 3 minutes, no distance involved) Apple Watch Series 10 (GPS) running watchOS 27.0.1 (24R365), paired to an iPhone 15 running iOS 27. Start an Other workout. Move your arms continuously for about 2 minutes (I use air punches). No treadmill, GPS, or distance calculation involved. End the workout and review the heart rate samples. Result: One heart rate sample at approximately 0:05, then no additional samples for the rest of the workout. Expected: Continuous heart rate sampling every few seconds, which is how the same watch behaved on watchOS 26. This reproduces 100% of the time across every workout type I've tried since updating to watchOS 27.0. It did not occur on watchOS 26 using the same watch, same wrist, and same fit. Key diagnostic: the sensor is working, the workout session path is not. The Heart Rate app reads immediately and continues updating every few seconds, even while a workout is running. Background heart rate sampling outside workout sessions works normally. Active energy for my daily 65-minute session is accurate when no workout is started (405 calories on 9/22/26, consistent with watchOS 26). Recording that same session as an Indoor Walk workout results in roughly half the active calories (typically 185-200 versus high-300s/low-400s before the update). Starting a workout appears to suppress a working measurement path and replace it with one that is failing. Downstream impact A 1:06:13 session has been credited as 9, 35, and 55 exercise minutes on different days. Since exercise-minute credit for walking is heart-rate driven, the lack of heart rate samples appears to directly affect exercise credit. Separate issue in the same build (not the subject of this post) Indoor distance is consistently about 50% low. A 1:06:13 walk at a constant 4.1 mph should be 4.52 miles, but the watch reports roughly 2-3 miles even though step counts are correct. The watchOS 27 User Guide describes a redesigned pedometer model using new machine-learning algorithms for treadmill distance. Series 12 and Ultra 4 owners are reporting the same shortfall with matching step counts, including on clean installs, so this does not appear to be hardware-specific. The heart rate dropout reproduces in the Other workout type, which performs no distance calculation, so the two issues appear to be independent regressions. Already ruled out Health details are correct Wrist Detection enabled Power Saving Mode off on both watch and iPhone Heart Rate and Fitness Tracking permissions enabled Motion Calibration & Distance enabled Watch fit and position unchanged Both devices restarted Fitness Calibration Data reset Full unpair/re-pair Multiple workout types tested Pause/resume mid-workout (heart rate briefly shows "Searching" and then drops out again) FB24834050 includes two sysdiagnoses from watchOS 27.0 and currently shows "Recent Similar Reports: More than 10." Status remains Open with no response. Ask Can anyone from Apple confirm whether this is a known/tracked issue? Also, would a sysdiagnose captured using the watchOS logging profile from the Apple bug-reporting site be useful? I'm happy to install the profile, reproduce the issue in under three minutes, and attach fresh logs. I'm also interested in hearing from developers using HKWorkoutSession. Are you seeing the same heart-rate sample gaps on watchOS 27 in your own apps? That would help determine whether this is specific to the Workout app or a regression in the workout session layer underneath it. Thanks!
3
2
312
4d
Workout route map double-converts the first ~49 samples on mainland-China tracks (FB25306175)
Every ride I import into HealthKit from a Chinese bike computer renders wrong at the start in the Fitness and Health apps, and the same record is wrong on iOS 26 as well as on iOS 27.2 (iPhone 15 Pro, mainland China, AutoNavi base map). Filed as FB25306175. WHAT HAPPENS The first ~49 samples of an HKWorkoutRoute are drawn about 415 m east and 222 m south of the coordinates actually stored, and a straight line joins that piece back to the rest of the track. The green start marker is on the displaced piece. Every remaining sample, and the red end marker, are drawn exactly where stored. On this record (2794 points, 1 Hz, 17649 m drawn) the displaced block is the first 209 m of riding — about 53 seconds The displacement is one more application of the local WGS-84 → GCJ-02 transform, which these coordinates already contain: measured from screenshots at native 1179×2556, 417 m E / 219 m S on the full-screen map and 418 m E / 220 m S on the summary map, against a true local offset of 415.2 m E / 222.4 m S. THE STORED DATA IS CORRECT HKWorkoutRouteQuery returns all 2794 CLLocation values unchanged; the descriptor query returns the same count and the same first/last values. One workout, one route. The same coordinates drawn with SwiftUI Map + MapPolyline on the same phone render correctly end to end, including the start. The same unchanged workout, opened twice with no write in between, was correct the first time and offset after leaving and re-entering. So the data is not the variable. THE WRITE PATH The head unit writes GCJ-02 into record.position_lat / position_long. That is what makes the track land on the road here: MKMapSnapshotter on the mainland base map puts the GCJ-02 values exactly on two known intersections, and the WGS-84 values about 470 m north-west of them, and MapKit does no conversion for us. So they are written verbatim: let config = HKWorkoutConfiguration() config.activityType = .cycling config.locationType = .outdoor let builder = HKWorkoutBuilder(healthStore: store, configuration: config, device: nil) try await builder.beginCollection(at: firstPoint.timestamp.addingTimeInterval(-1)) // CLLocation per record, coordinates as recorded, horizontalAccuracy 10, // verticalAccuracy 10 (or -1 where the record has no altitude), recorded altitude // and speed, course computed from the previous point. let routeBuilder = builder.seriesBuilder(for: HKSeriesType.workoutRoute()) as? HKWorkoutRouteBuilder for batch in locations.chunked(into: 1000) { try await routeBuilder?.insertRouteData(batch) } try await builder.endCollection(at: lastPoint.timestamp.addingTimeInterval(10)) let workout = await builder.finishWorkout()WHAT IS NOT THE CAUSE Established with controlled synthetic routes written from the same start point: probe sample interval m per point displaced length displaced time samples E 1 s 10 ~480 m ~48 s ~49 F 2 s 10 ~480 m ~96 s ~49 G 1 s 20 ~950 m ~48 s ~49 The block follows SAMPLE COUNT, not time and not distance. Also ruled out, each by writing a variant: lap and pause/resume events (present, absent, and a 206-point probe carrying all three); the first point's metadata (altitude 0 / course -1 / verticalAccuracy -1); valid versus -1 values for horizontalAccuracy, verticalAccuracy, speed and course; dropping an isolated leading point; back-dating the first timestamp to the workout start; trimming the leading 200 m (the offset simply re-appears at the new start, which still begins with 49 samples). Writing WGS-84 instead inverts the symptom — the leading block then looks right and everything else goes ~470 m north-west — which is what you would expect if only the leading block is converted a second time. SCOPE This is not my one file. Three separate real rides, two cities, two head units, plus synthetic routes, all behave identically: MAGENE C706_54634 Suzhou 2026-10-23 17.61 km 2797 records / 2794 stored points MAGENE C706_54634 Suzhou 2026-10-22 12.66 km 2076 records MAGENE C606P_33206 Chengdu 2026-10-20 63.30 km 12069 records Apple Watch recordings made in mainland China render correctly, and a Garmin Edge 1050 file recorded in the US imported through the same code path renders correctly. The common factor is coordinates that are already GCJ-02 when they reach HKWorkoutRouteBuilder — which is every Chinese bike computer, every Chinese running app, and every GPX export from a Chinese service. So any third-party importer here hits this. WHAT I AM ASKING Does the workout map apply a datum conversion to a leading block of route samples, and is that block size fixed? What is the official coordinate contract for HKWorkoutRoute locations for apps working with GCJ-02 data in mainland China? Is there a supported way to opt out, and what decides whether a given route enters this state? Which component owns the conversion — Health/Fitness route rendering or MapKit? I am deliberately not pre-converting the first ~49 points: that would store mixed datums in HealthKit, wrong for the Health app itself, for exports, for every third-party reader, and wrong for all of them the moment this is fixed. Happy to share the one-tap sample project, the exported JSON with all 2794 stored CLLocation values, the original .fit, and the probe E/F/G screenshots — reply here and I'll attach them.
1
0
94
6d
Can watchOS apps access Apple-generated sleep stages in real time for a smart alarm?
I’m evaluating a native watchOS smart-alarm app and would like to clarify whether public APIs support its core requirement before building a prototype. The app would wake the user during a 20–30-minute window before their selected alarm time, using Apple Watch’s own sleep-stage classifications available through HealthKit’s sleepAnalysis category: Core, Deep, REM, and Awake. I have reviewed HKCategoryValueSleepAnalysis, HKAnchoredObjectQuery, HKObserverQuery, background delivery, and WKExtendedRuntimeSession’s Smart Alarm mode. However, I haven’t found documentation establishing when Apple-generated sleep-stage samples become available during an ongoing sleep session. Could you clarify: Are Apple-generated sleep-stage samples written to the Watch’s local HealthKit store during sleep, or only after the sleep session ends or subsequent processing? If available during sleep, is there any documented update cadence or latency that would make them suitable for a smart alarm? Should the latest sample be treated only as a retrospective classification rather than the current sleep stage? Can an app query these samples during a Smart Alarm extended runtime session while the Watch is worn and unlocked, with its display off and Sleep Focus enabled? Are there relevant execution or data-access restrictions? If this use case is unsupported, is there any public API that exposes Apple’s current sleep-stage estimate? If not, which Feedback Assistant category is appropriate for requesting this capability? The intended approach queries HealthKit directly on Apple Watch, without depending on Watch-to-iPhone synchronization, and retains a fixed latest wake-up time as a fallback. This is an API feasibility question, not a reproduced bug. I haven’t yet built or tested a prototype. Thank you.
2
0
245
1w
Extended Runtime API - Health Monitoring
In the WWDC 2019 session "Extended Runtime for WatchOS apps" the video talks about an entitlement being required to use the HR sensor judiciously in the background. It provides a link to request the entitlement which no longer works: http://developer.apple.com/contect/request/health-monitoring The session video is also quite hard to find these days. Does anyone know why this is the case? Is the API and entitlement still available? Is there a supported way to run, even periodically, in the background on the Watch app (ignoring the background observer route which is known to be unreliable) and access existing HR sensor data
16
1
2.9k
1w
iOS 27 Health permissions: a reckoning is coming
iOS 27 adds a second stage to HealthKit read authorization. After picking data types, the user chooses "Past 30 Days and Future Data" or "All Recorded Data and Future Data", with Allow disabled until one is selected. Every user of every health app now makes this call, in the first seconds of onboarding, with no real context about what the app needs. I don't think the scale of this has landed yet. A meaningful share of users will pick 30 days. multi-year health trends, month to month comparisons, all-time records: with 30 days these features don't get worse, they stop existing. And it breaks silently. The user sees empty charts and a app that doesn't do what the screenshots promised. They won't connect that to a sheet they tapped through on day one — they'll connect it to the app. That's the reckoning: a wave of one-star reviews and support mail for a decision the developer never saw and can't inspect. Because we can't inspect it .authorizationStatus(for:) deliberately hides read authorization and getRequestStatusForAuthorization only says whether prompting would show UI, so a 30-day grant and a genuinely new Apple Watch user look identical from the query layer. A callback when Health permissions change for a type — even without disclosing the new state — would go a long way here. And we can't route users to the fix. UIApplication.openSettingsURLString opens the app's own Settings page, which has no Health section. The real control sits at Settings › Privacy & Security › Health › — four levels deep, unreachable from any public API. My suggestion is a URL constant scoped to the calling app, the way openNotificationSettingsURLString (iOS 15.4+) and openDefaultApplicationsSettingsURLString (iOS 18.3+) already work. But that's just my idea; if there's a better mitigation, or something already planned, I'd like to hear it. Worth saying the privacy gain looks thin either way: the app keeps all future data indefinitely, so a 30-day grant becomes a full-history grant in thirty days for anyone who keeps the app. The window limits what's readable today, not what accumulates. iOS 27 release is approaching... I think this will cause problems 😞 Filed as FB24398048 and FB24398031
2
0
1.2k
1w
Intermittent missing historical step counts from HKStatisticsCollectionQuery on iOS 27 beta
Hello, We received a customer report about intermittent missing historical step-count data when using HKStatisticsCollectionQuery on iOS 27 beta. When the query was executed on August 16, only the most recent two days—August 16 and August 15—returned correct step counts. Earlier dates returned nil from sumQuantity() and were consequently treated as zero. However, queries executed on August 14 and August 18 returned the expected data. Therefore, the problem appears to be intermittent rather than consistently reproducible. The customer confirmed that all affected historical step counts were visible in the Apple Health app, including the dates returned as zero by our query. We have not received the same type of customer report from devices running iOS 26 or earlier. Here is a simplified version of our query: guard let stepType = HKObjectType.quantityType( forIdentifier: .stepCount ) else { return } var calendar = Calendar(identifier: .gregorian) calendar.timeZone = TimeZone(identifier: "Asia/Seoul")! let queryStartDate = calendar.startOfDay(for: parsedStartDate) let tomorrow = calendar.date(byAdding: .day, value: 1, to: Date())! let queryEndDate = calendar.startOfDay(for: tomorrow) let datePredicate = HKQuery.predicateForSamples( withStart: queryStartDate, end: queryEndDate, options: .strictStartDate ) let nonUserEnteredPredicate = HKQuery.predicateForObjects( withMetadataKey: HKMetadataKeyWasUserEntered, operatorType: .notEqualTo, value: NSNumber(value: true) ) let predicate = NSCompoundPredicate( andPredicateWithSubpredicates: [ datePredicate, nonUserEnteredPredicate ] ) let anchorDate = calendar.startOfDay(for: Date()) var interval = DateComponents() interval.day = 1 let query = HKStatisticsCollectionQuery( quantityType: stepType, quantitySamplePredicate: predicate, options: .cumulativeSum, anchorDate: anchorDate, intervalComponents: interval ) query.initialResultsHandler = { _, results, error in guard let results, error == nil else { print("Query error: \(String(describing: error))") return } results.enumerateStatistics( from: queryStartDate, to: queryEndDate ) { statistics, _ in let steps = statistics .sumQuantity()? .doubleValue(for: .count()) ?? 0 print(statistics.startDate, statistics.endDate, steps) } } healthStore.execute(query) Observed behavior Query executed on August 14: historical step counts returned correctly Query executed on August 16: August 16 and August 15 returned correctly August 14 and earlier returned nil from sumQuantity() Query executed on August 18: historical step counts returned correctly again No query error was reported All step counts remained visible in the customer's Apple Health app Expected behavior The query should consistently return cumulative daily step counts when matching HealthKit samples exist and are visible in the Health app. Because this was reported through customer support, we do not currently know the exact iOS 27 beta build number. We are also unable to reproduce it consistently on our own test devices. Questions Is there a known intermittent issue with historical .stepCount queries on iOS 27 beta? Can HealthKit temporarily return incomplete statistics while data is being indexed, synchronized, or migrated? Is there a recommended way to detect that the returned statistics are temporarily incomplete? Should applications retry the query when older statistics unexpectedly return nil without an error? We have not received reports of this behavior from customers using iOS 26 or earlier. Thank you.
3
0
945
1w
watchOS 27: Environmental Audio Exposure sampling became extremely sparse
After updating my Apple Watch Series 10 to the public release of watchOS 27, Environmental Sound Level measurements became extremely sparse. Before watchOS 27, with Environmental Sound Measurements enabled, my watch recorded environmental sound data approximately every 30 seconds and the coverage was nearly continuous throughout the day. After updating the same Apple Watch to watchOS 27, the behavior changed significantly: Environmental Sound Level samples are much less frequent Large gaps appear between measurements Overall daily temporal coverage is dramatically reduced The same change is visible both in the Health app and through HealthKit using HKQuantityTypeIdentifier.environmentalAudioExposure No relevant settings were changed, and Environmental Sound Measurements are still enabled. This is important for apps that use Environmental Audio Exposure data for time-based analysis. In my case, I use this data for sleep and nap environment analysis. With the much sparser sampling on watchOS 27, it is difficult to reliably evaluate the acoustic environment during a specific sleep period. I have also seen other watchOS 27 users reporting similar behavior: https://www.reddit.com/r/watchOSBeta/comments/1wjrdaq/watchos_27_broke_the_noise_monitoring_app/ I submitted a Feedback Assistant report: FB24837491 Has anyone else observed the same change on watchOS 27? I’m especially interested in whether this is: an intentional change to the sampling or aggregation strategy, a HealthKit write-frequency change, or a regression in watchOS 27. If anyone has compared HKQuantitySample.startDate, endDate, sample duration, and sample interval before and after the watchOS 27 update, that data would be very useful for comparison.
2
1
440
2w
Is frequent heart-rate delivery during a paused Mind & Body workout supported?
I am developing a watchOS wellness app with explicitly user-started monitoring during ordinary daily activities. The goal is timely physiological-change check-ins over an approximately eight-to-ten-hour monitoring period, including when the display is off. This is not exercise monitoring or a diagnostic use case. The relevant API sequence is: Create HKWorkoutConfiguration with activityType .mindAndBody and locationType .unknown. Create HKWorkoutSession, its associated HKLiveWorkoutBuilder and HKLiveWorkoutDataSource; set the session and builder delegates. Restrict builder collection to heart rate, then call startActivity(with:) and beginCollection(withStart:). After receiving initial live HR, call HKWorkoutSession.pause(). Receive .heartRate through workoutBuilder(_:didCollectDataOf:) and read statistics(for:), mostRecentQuantity() and mostRecentQuantityDateInterval(). When the user ends monitoring, end collection and discard the workout rather than save it. In development tests on Apple Watch hardware, HR callbacks have continued for hours after pausing, including while backgrounded, with roughly five-second average intervals. Some tests have shown gaps. I do not assume that observing this behavior establishes a supported API guarantee. Is frequent live-builder HR delivery in the paused state officially supported, or is this behavior an implementation detail that an app must not rely on? Is there a supported watchOS API or architecture for this non-exercise monitoring goal, and what are its HR-delivery/background-runtime limits? The app uses HealthKit and HealthKit background-delivery entitlements and the workout-processing background mode. I would also appreciate clarification about possible Activity-ring or energy-calculation effects when the workout is paused and ultimately discarded.I am developing a watchOS wellness app with explicitly user-started monitoring during ordinary daily activities. The goal is timely physiological-change check-ins over an approximately eight-to-ten-hour monitoring period, including when the display is off. This is not exercise monitoring or a diagnostic use case. The relevant API sequence is: Create HKWorkoutConfiguration with activityType .mindAndBody and locationType .unknown. Create HKWorkoutSession, its associated HKLiveWorkoutBuilder and HKLiveWorkoutDataSource; set the session and builder delegates. Restrict builder collection to heart rate, then call startActivity(with:) and beginCollection(withStart:). After receiving initial live HR, call HKWorkoutSession.pause(). Receive .heartRate through workoutBuilder(_:didCollectDataOf:) and read statistics(for:), mostRecentQuantity() and mostRecentQuantityDateInterval(). When the user ends monitoring, end collection and discard the workout rather than save it. In development tests on Apple Watch hardware, HR callbacks have continued for hours after pausing, including while backgrounded, with roughly five-second average intervals. Some tests have shown gaps. I do not assume that observing this behavior establishes a supported API guarantee. Is frequent live-builder HR delivery in the paused state officially supported, or is this behavior an implementation detail that an app must not rely on? Is there a supported watchOS API or architecture for this non-exercise monitoring goal, and what are its HR-delivery/background-runtime limits? The app uses HealthKit and HealthKit background-delivery entitlements and the workout-processing background mode. I would also appreciate clarification about possible Activity-ring or energy-calculation effects when the workout is paused and ultimately discarded.
0
0
54
2w
HealthKit: Historical pool workout locations for a personal swimming map
Hello Apple Developer Relations and the HealthKit team, I'm a hobbyist developer and recreational swimmer building a personal app to make better use of my own Apple Watch workout data. My goal is training management, post-workout reviews, and long-term summaries of my swimming history. Design goal I would like to create a global map of places where I have swum, similar to the map view in Apple Photos: When zoomed out, group locations by country or region and show the number of distinct swimming places, rather than the number of workouts. When zoomed in, reveal individual places and their associated workouts. Venue or water-body names could be added later where they can be reliably identified. For pool swimming, a single location point is sufficient. A route is not required. For open-water swimming, show the place first, then reveal an individual workout's route when selected. Group repeated visits to the same place while retaining each workout for review. Data requirement The key requirement is read-only access to a location associated with an existing workout, including historical pool workouts recorded using Apple's Workout app. A coordinate linked to the workout would be enough to begin with; I am not expecting HealthKit to identify or name the venue. What I have observed In on-device tests, I can read routes for open-water swimming workouts. For the historical pool workouts I checked, no route was returned, and I did not find usable location coordinates in the public workout, activity, event, or route metadata I inspected. However, Apple Fitness displays a map point for historical pool workouts. The absence of a route therefore does not establish the absence of a recorded location. I have read the DTS response explaining that there is currently no public API for third-party access to indoor workout locations: https://developer.apple.com/forums/thread/827939 Current obstacle Without a supported way to obtain these historical points, the app cannot automatically build a useful map of past pool visits. Recording locations from now on or asking users to assign old workouts manually would not recover the existing history. A computer-backup extraction workflow also would not meet the intended standalone iPhone app experience. Questions and enhancement request Beyond the current HealthKit APIs, is there any supported, user-initiated export or import path that preserves historical indoor workout coordinates and their association with the workout? If there is no supported path today, could Apple consider read-only access to historical workout locations through HealthKit, with explicit user authorization and clear handling of missing or approximate locations? I understand that a formal enhancement request belongs in Feedback Assistant. I am sharing this concrete design and data requirement here to clarify the use case and ask whether a supported alternative already exists. Thank you for considering this request.
0
0
116
4w
Export PDF from Apple Health app in iOS 27.2 beta
We depend on the Export PDF button in previous Apple Health apps and it seems to have disappeared in 27.2 beta. Merging FHIR results from multiple hospitals, pharmacies and other patient portals is complex. Apple does an excellent job of merging, categorizing, and displaying this information in the app and it used to generate a great human-readable PDF export. Exporting individual categories as a PDF would be fussy and unreliable for a typical user. Is this regression in the beta an oversight or a strategic shift on the part of Apple to deprive users of an easy to use combined patient summary?
1
0
163
4w
HKStatisticsCollectionQueryDescriptor intermittently returns no data for certain date ranges on iOS 27
We are seeing inconsistent results from HKStatisticsCollectionQueryDescriptor on iOS 27. Using the same quantity type, statistics options, anchor date, interval components, and predicate configuration, some date ranges return the expected statistics, while other ranges unexpectedly return empty results or buckets with no quantity. The affected ranges do contain HealthKit samples: HKSampleQueryDescriptor finds samples in the same date range. HKStatisticsQueryDescriptor returns the expected value when run separately for an affected bucket. HKStatisticsCollectionQueryDescriptor returns no quantity for that same bucket. Slightly expanding or shifting the date range may cause the collection query to return data again. A simplified version of the query looks like this: let datePredicate = HKQuery.predicateForSamples( withStart: startDate, end: endDate, options: .strictStartDate ) let descriptor = HKStatisticsCollectionQueryDescriptor( predicate: .quantitySample( type: quantityType, predicate: datePredicate ), options: .cumulativeSum, anchorDate: anchorDate, intervalComponents: DateComponents(day: 1) ) let collection = try await descriptor.result(for: healthStore) collection.enumerateStatistics(from: startDate, to: endDate) { statistics, _ in let quantity = statistics.sumQuantity() print(statistics.startDate, quantity as Any) } Expected behavior Every interval containing matching samples should return the corresponding statistics, regardless of the overall requested date range. Actual behavior Some date ranges produce missing or empty buckets even though matching samples exist and an individual HKStatisticsQueryDescriptor can calculate the expected value. Changing only the date range can make the data appear or disappear. The samples are visible to the app in the affected range, so this does not appear to be explained solely by iOS 27’s Limited History authorization. This behavior was not observed with the same query flow on earlier iOS versions. Is this a known regression in HKStatisticsCollectionQueryDescriptor on iOS 27, or has the expected date-range or predicate behavior changed?
3
3
1.1k
Oct ’26
Unable to invalidate interval: no data source available error when fetching steps using HKStatisticsCollectionQuery
While attempting to read a user’s daily step history spanning backward to the last 7 days, a small but consistent subset of users encounter Error Code 3 with the underlying error description: Error Code 3 "Unable to invalidate interval: no data source available." When this error occurs, we are entirely unable to read their step history. We have received ~10 direct user reports of this within the last couple of weeks.
15
2
2.3k
Sep ’26
Apple Watch Health data stopped syncing to iPhone — FB24923176
Health and Workout data stopped syncing from my Apple Watch to my iPhone on 21 September while both devices were on the public releases. The Watch continues recording the data and the missing data remains on the Watch. Activity Sharing also continues to work. I’ve since installed the matching iOS/watchOS developer betas in an attempt to resolve the pre-existing issue, but it remains. And now I cannot get assistance via the usual Apple Support route. I’ve submitted a Feedback Assistant report with both iOS and watchOS sysdiagnoses: FB24923176. Multiple users are also reporting this issue here - https://www.reddit.com/r/AppleWatch/comments/1whu0at/apple_watch_workoutshealth_data_stopped_syncing/ Could someone advise whether this can be reviewed by the appropriate HealthKit/watchOS team? I am deliberately avoiding unpairing the Watch because the unsynced data is currently only stored on the Watch. Thanks so much!
0
0
334
Sep ’26
SensorKit PPG Access and Optical Sensor Specifications for Apple Watch Series 9 Research
We are an interdisciplinary research team involving Gazipaşa Science High School and Akdeniz University in Türkiye, including student researchers, a project advisor, and a medical researcher. We are conducting a non-commercial scientific research project within the TÜBİTAK 2204-A High School Students Research Projects Competition. As part of the project, we are developing an experimental wrist-based optical monitoring system. We plan to use an Apple Watch Series 9 (A2980, Part Number MR9A3TU/A) as a comparative benchmark during the development and evaluation of our system. In particular, we are interested in accessing Apple Watch photoplethysmography (PPG) data through SensorKit. We intend to use these data to support the iterative development of our optical monitoring system and to evaluate and report how modifications to our system affect its signal characteristics and performance relative to an established commercial wearable optical sensing platform. Apple Watch measurements will be used for comparative research and system evaluation, rather than as a clinical reference or diagnostic measurement. We would therefore appreciate guidance on the appropriate procedure for obtaining SensorKit access and the required entitlement for Apple Watch PPG data for this type of scientific research. To perform a scientifically meaningful comparison, we also need reliable technical information about the optical sensing system of the Apple Watch used in our study. However, we have been unable to find an authoritative and citable Apple source specifying the wavelengths or wavelength ranges of the optical emitters used in the Apple Watch Series 9 (A2980). Could you please direct us to any official Apple documentation, publication, technical specification, or other authoritative resource containing this information? If the exact specifications are not publicly available, we would appreciate guidance on whether such information can be provided for academic research purposes. We would also appreciate recommendations for the appropriate Apple technical support channel, Developer Forum, research contact, or other point of contact for further questions that may arise during the development and research process. Thank you for your time and guidance.
1
0
297
Sep ’26
Health sleep score incorrect in 27.2
I have 27.2 developer beta running on my iPhone Air and Watch Ultra 4. My wife has an 18 Pro and also Ultra 4 but hers are both running the current public release versions of iOS 27 and watchOS 27. After 2 nights with the Ultra 4's, her sleep score is reporting accurate. Mine is way off. For example, last night we went to bed around 10 PM and woke up at 7 AM. Her scores were in the 90's with 7:36 hours of sleep. Mine is in the 40's with 4:20 hours of sleep. We both slept the same/great last night. Similar results for the night before - hers is accurate; mine are way off.
1
0
171
Sep ’26
Maintaining a Core Bluetooth connection on watchOS for the duration of an HKWorkoutSession
I have a watchOS app that records workouts on a piece of Bluetooth LE fitness equipment. It runs an HKWorkoutSession and, for the length of that session, stays connected to the machine and subscribed to a characteristic that reports step data once a second. Each notification is recorded into the workout's HKLiveWorkoutBuilder. The connection needs to last as long as the workout — typically 20–60 minutes. The watch app declares both: WKBackgroundModes = workout-processing UIBackgroundModes = bluetooth-central This works indefinitely while the app is in the foreground. When the app leaves the foreground — the user lowers their wrist or goes to the watch face — the peripheral disconnects after roughly three minutes, and the workout loses the rest of its data. What we have been able to establish from logs at the moment of the disconnect: The app is not suspended. Notifications arrive at a steady 1 Hz with no gaps right up to the disconnect (271 and 272 consecutive notifications in two separate cases), so the workout session is keeping the app running as expected. centralManager.state is .poweredOn. centralManager(_:didDisconnectPeripheral:error:) is called with error == nil, and the peripheral's state is .disconnected. Nothing in our code calls cancelPeripheralConnection at that point; our own teardown runs afterwards, in response to the disconnect. The user is still using the machine, and the machine is still notifying. Reproducible: two captures roughly three minutes and twenty seconds after the app backgrounded. I understand from Get timely alerts from Bluetooth devices on watchOS (WWDC22) that background Bluetooth on watchOS is intended for timely alerts, with a limited number of background runtime opportunities, and that periodic data collection should use Background App Refresh instead. Our data arrives once a second for the whole workout, so I assume we are well outside what that mode is budgeted for, and that the disconnect is the system reclaiming the link. My questions: Does a running HKWorkoutSession grant any exemption from the background Bluetooth limits? workout-processing clearly keeps the app executing — we receive notifications for minutes after backgrounding — but the connection is still torn down. Is Bluetooth's background budget independent of the workout runtime, and is that the intended behaviour? Is there a supported way to hold a BLE connection for the duration of a workout session? Reading a fitness machine's telemetry for an entire workout seems like a mainstream use of both frameworks together, but I cannot find a configuration that survives the app leaving the foreground. Would a longer connection interval change this? The session recommends at least 150 ms. If the disconnect is driven by connection-event volume rather than notification count, a slower interval or a lower update rate may be the answer — and if so, is there a documented threshold to aim for? error == nil on disconnect. The documentation says a nil error means the disconnect was requested locally via cancelPeripheralConnection, which we do not call here. Should a system-initiated reclaim of the link be reported this way, or is there a more specific error we should be looking for? We now log the error on peripheral(_:didUpdateValueFor:error:) to catch LeGattNearBackgroundNotificationLimit and LeGattExceededBackgroundNotificationLimit, but have not yet observed either before a disconnect. Is there any entitlement path for this? We are aware of com.apple.developer.bluetooth-central-background and that it is limited to continuous glucose monitoring. Is there an equivalent route for fitness equipment, or is foreground-only the expected design for this class of app? If continuous background Bluetooth is simply not available here, I would like to know that clearly, so I can design around the disconnect — reconnecting mid-workout rather than treating a dropped link as the end of the session.
0
0
257
Sep ’26
Measuring continuous heart rate without using HKWorkoutSession?
I'm writing a Watch app where we have an in-built protocol for measuring resting heart rate. The user taps start and the heart rate is measured for 30 minutes while they're lying down. It works well, but because I'm using HKWorkoutSession to do this, the green exercise ring is advancing by 30 minutes even though the user is not exercising. So, any way to get continuous heart rate measurements without using HKWorkoutSession?
1
0
229
Sep ’26
WatchOS HealthKit HKObserverQuery crashes in background
I have a watchOS app with a connected iOS app using Swift and SwiftUI. The watchOS app should read heart rate date in the background using HKOberserQuery and enableBackgroundDelivery(), send the data to the iPhone app via WCSession. The iPhone app then sends the data to a Firebase project. The issue I am facing now it that the app with the HKObserverQuery works fine when the app is in the foreground, but when the app runs in the background, the observer query gets triggered for the first time (after one hour), but then always get terminated from the watchdog timeout with the following error message: CSLHandleBackgroundHealthKitQueryAction scene-create watchdog transgression: app<app.nanacare.nanacare.nanaCareHealthSync.watchkitapp((null))>:14451 exhausted real (wall clock) time allowance of 15.00 seconds I am using Xcode 16.3 on MacOS 15.4 The App is running on iOS 18.4 and watchOS 11.4 What is the reason for this this issue? I only do a simple SampleQuery to fetch the latest heart rate data inside the HKObserverQuery and then call the completionHandler. The query itself takes less than one second. Or is there a better approach to read continuously heart rate data from healthKit in the background on watchOS? I don't have an active workout session, and I don't need all heart rate data. Once every 15 minutes or so would be enough.
13
1
2.1k
Aug ’26
HealthKit workout deletion does not remove Exercise Minutes and Active Energy generated during the session
I’m developing a watchOS application for Apple Watch Ultra 2 that continuously monitors heart rate during non-sporting activities, such as driving. The application uses: ● HKWorkoutSession ● HKLiveWorkoutBuilder ● HKAnchoredObjectQuery to retrieve heart rate samples I have observed that starting a workout session allows frequent heart rate measurements to continue even when the Apple Watch display becomes dimmed. However, this creates an unwanted side effect: although the user is not exercising, the session contributes to the Activity rings. In my tests, a workout recorded as type .other generated Exercise Minutes and Active Energy, even though the saved workout itself reported 0 active calories. The problem occurs when deleting the workout. After selecting Delete Workout & Data in the Health/Fitness interface: 1. The workout disappears from the workout history. 2. The Exercise Minutes generated during the session remain in HealthKit. 3. The Active Energy samples generated during the same interval also remain. 4. The corresponding Activity ring totals are not immediately corrected. I subsequently deleted the Exercise Minutes samples manually from the Health app. This corrected the numerical Exercise Minutes total. The Active Energy samples required separate handling. In some tests, the numerical values and the graphical representation of the Activity rings also appeared temporarily inconsistent. My questions are: 1. Is this the expected behavior of HealthKit when deleting a workout created using HKWorkoutSession and HKLiveWorkoutBuilder? 2. Why does Delete Workout & Data leave Exercise Minutes and Active Energy samples generated during the workout interval? 3. Are these samples considered independent system-generated measurements rather than data associated with the workout? 4. Is there a supported way to prevent a monitoring session from contributing to the Activity rings while still maintaining frequent heart rate acquisition in the background? My objective is to monitor physiological parameters during activities that are not exercise, without modifying the user’s fitness statistics. I would appreciate clarification about the intended behavior of these APIs and the recommended implementation approach.
Replies
2
Boosts
0
Views
79
Activity
1d
Health rejects CDA XML import on iOS 27.2 beta 4 — compatibility requirements? FB25204405
Hello, I’m investigating CDA XML compatibility with the Health app’s medical document import feature. Health rejects both custom CDA documents and an unchanged public HL7 CCD sample with a generic “No medical documents were found to import” error. Feedback Assistant report: FB25204405. Environment: iPhone 15 Pro Max iOS 27.2 beta 4 (24B5110a) Device language: Hebrew Region: Israel Steps to reproduce: Save a CDA XML document in Files. Open the document’s share sheet and select Health. Health opens but displays an error instead of a document preview or import confirmation. The exact Hebrew error is: “לא ניתן לייבא מסמכים רפואיים” “לא נמצאו מסמכים רפואיים לייבוא.” Approximate English translation: “Unable to Import Medical Documents” “No medical documents were found to import.” For comparison, I also tried the unchanged public HL7 CCD sample containing fictional patient data: https://github.com/HL7/CDA-core-2.0/blob/master/examples/sampleCCD.xml This sample produces the same error. I understand that being an HL7 sample does not necessarily mean it satisfies all of Health’s import requirements. My questions: Is standalone CDA XML import from Files into Health supported through this workflow? Are there specific CDA profiles, header fields, filename extensions, or packaging requirements needed for Health to recognize the document? Has anyone successfully imported a CDA document on this build, or identified a workaround? Is there a recommended way to distinguish a document validation failure from a file recognition or handoff failure? Testing so far has been limited to the Health app’s user interface. I have not tested the document through HKCDADocumentSample in a native app, and I have not established whether this is a regression from an earlier iOS version. I would appreciate guidance on the supported workflow or a public, fictional-data sample known to work with Health. Please do not share real patient records. Thank you.
Replies
1
Boosts
1
Views
131
Activity
2d
watchOS 27 Workout sessions record almost no heart rate samples (Series 10) - FB24834050
Filed as FB24834050. Still reproducible on watchOS 27.0.1 (24R365). Posting here in case an Apple engineer can help route it, and to see whether other developers are seeing the same behavior through HealthKit. Minimal reproduction (under 3 minutes, no distance involved) Apple Watch Series 10 (GPS) running watchOS 27.0.1 (24R365), paired to an iPhone 15 running iOS 27. Start an Other workout. Move your arms continuously for about 2 minutes (I use air punches). No treadmill, GPS, or distance calculation involved. End the workout and review the heart rate samples. Result: One heart rate sample at approximately 0:05, then no additional samples for the rest of the workout. Expected: Continuous heart rate sampling every few seconds, which is how the same watch behaved on watchOS 26. This reproduces 100% of the time across every workout type I've tried since updating to watchOS 27.0. It did not occur on watchOS 26 using the same watch, same wrist, and same fit. Key diagnostic: the sensor is working, the workout session path is not. The Heart Rate app reads immediately and continues updating every few seconds, even while a workout is running. Background heart rate sampling outside workout sessions works normally. Active energy for my daily 65-minute session is accurate when no workout is started (405 calories on 9/22/26, consistent with watchOS 26). Recording that same session as an Indoor Walk workout results in roughly half the active calories (typically 185-200 versus high-300s/low-400s before the update). Starting a workout appears to suppress a working measurement path and replace it with one that is failing. Downstream impact A 1:06:13 session has been credited as 9, 35, and 55 exercise minutes on different days. Since exercise-minute credit for walking is heart-rate driven, the lack of heart rate samples appears to directly affect exercise credit. Separate issue in the same build (not the subject of this post) Indoor distance is consistently about 50% low. A 1:06:13 walk at a constant 4.1 mph should be 4.52 miles, but the watch reports roughly 2-3 miles even though step counts are correct. The watchOS 27 User Guide describes a redesigned pedometer model using new machine-learning algorithms for treadmill distance. Series 12 and Ultra 4 owners are reporting the same shortfall with matching step counts, including on clean installs, so this does not appear to be hardware-specific. The heart rate dropout reproduces in the Other workout type, which performs no distance calculation, so the two issues appear to be independent regressions. Already ruled out Health details are correct Wrist Detection enabled Power Saving Mode off on both watch and iPhone Heart Rate and Fitness Tracking permissions enabled Motion Calibration & Distance enabled Watch fit and position unchanged Both devices restarted Fitness Calibration Data reset Full unpair/re-pair Multiple workout types tested Pause/resume mid-workout (heart rate briefly shows "Searching" and then drops out again) FB24834050 includes two sysdiagnoses from watchOS 27.0 and currently shows "Recent Similar Reports: More than 10." Status remains Open with no response. Ask Can anyone from Apple confirm whether this is a known/tracked issue? Also, would a sysdiagnose captured using the watchOS logging profile from the Apple bug-reporting site be useful? I'm happy to install the profile, reproduce the issue in under three minutes, and attach fresh logs. I'm also interested in hearing from developers using HKWorkoutSession. Are you seeing the same heart-rate sample gaps on watchOS 27 in your own apps? That would help determine whether this is specific to the Workout app or a regression in the workout session layer underneath it. Thanks!
Replies
3
Boosts
2
Views
312
Activity
4d
Workout route map double-converts the first ~49 samples on mainland-China tracks (FB25306175)
Every ride I import into HealthKit from a Chinese bike computer renders wrong at the start in the Fitness and Health apps, and the same record is wrong on iOS 26 as well as on iOS 27.2 (iPhone 15 Pro, mainland China, AutoNavi base map). Filed as FB25306175. WHAT HAPPENS The first ~49 samples of an HKWorkoutRoute are drawn about 415 m east and 222 m south of the coordinates actually stored, and a straight line joins that piece back to the rest of the track. The green start marker is on the displaced piece. Every remaining sample, and the red end marker, are drawn exactly where stored. On this record (2794 points, 1 Hz, 17649 m drawn) the displaced block is the first 209 m of riding — about 53 seconds The displacement is one more application of the local WGS-84 → GCJ-02 transform, which these coordinates already contain: measured from screenshots at native 1179×2556, 417 m E / 219 m S on the full-screen map and 418 m E / 220 m S on the summary map, against a true local offset of 415.2 m E / 222.4 m S. THE STORED DATA IS CORRECT HKWorkoutRouteQuery returns all 2794 CLLocation values unchanged; the descriptor query returns the same count and the same first/last values. One workout, one route. The same coordinates drawn with SwiftUI Map + MapPolyline on the same phone render correctly end to end, including the start. The same unchanged workout, opened twice with no write in between, was correct the first time and offset after leaving and re-entering. So the data is not the variable. THE WRITE PATH The head unit writes GCJ-02 into record.position_lat / position_long. That is what makes the track land on the road here: MKMapSnapshotter on the mainland base map puts the GCJ-02 values exactly on two known intersections, and the WGS-84 values about 470 m north-west of them, and MapKit does no conversion for us. So they are written verbatim: let config = HKWorkoutConfiguration() config.activityType = .cycling config.locationType = .outdoor let builder = HKWorkoutBuilder(healthStore: store, configuration: config, device: nil) try await builder.beginCollection(at: firstPoint.timestamp.addingTimeInterval(-1)) // CLLocation per record, coordinates as recorded, horizontalAccuracy 10, // verticalAccuracy 10 (or -1 where the record has no altitude), recorded altitude // and speed, course computed from the previous point. let routeBuilder = builder.seriesBuilder(for: HKSeriesType.workoutRoute()) as? HKWorkoutRouteBuilder for batch in locations.chunked(into: 1000) { try await routeBuilder?.insertRouteData(batch) } try await builder.endCollection(at: lastPoint.timestamp.addingTimeInterval(10)) let workout = await builder.finishWorkout()WHAT IS NOT THE CAUSE Established with controlled synthetic routes written from the same start point: probe sample interval m per point displaced length displaced time samples E 1 s 10 ~480 m ~48 s ~49 F 2 s 10 ~480 m ~96 s ~49 G 1 s 20 ~950 m ~48 s ~49 The block follows SAMPLE COUNT, not time and not distance. Also ruled out, each by writing a variant: lap and pause/resume events (present, absent, and a 206-point probe carrying all three); the first point's metadata (altitude 0 / course -1 / verticalAccuracy -1); valid versus -1 values for horizontalAccuracy, verticalAccuracy, speed and course; dropping an isolated leading point; back-dating the first timestamp to the workout start; trimming the leading 200 m (the offset simply re-appears at the new start, which still begins with 49 samples). Writing WGS-84 instead inverts the symptom — the leading block then looks right and everything else goes ~470 m north-west — which is what you would expect if only the leading block is converted a second time. SCOPE This is not my one file. Three separate real rides, two cities, two head units, plus synthetic routes, all behave identically: MAGENE C706_54634 Suzhou 2026-10-23 17.61 km 2797 records / 2794 stored points MAGENE C706_54634 Suzhou 2026-10-22 12.66 km 2076 records MAGENE C606P_33206 Chengdu 2026-10-20 63.30 km 12069 records Apple Watch recordings made in mainland China render correctly, and a Garmin Edge 1050 file recorded in the US imported through the same code path renders correctly. The common factor is coordinates that are already GCJ-02 when they reach HKWorkoutRouteBuilder — which is every Chinese bike computer, every Chinese running app, and every GPX export from a Chinese service. So any third-party importer here hits this. WHAT I AM ASKING Does the workout map apply a datum conversion to a leading block of route samples, and is that block size fixed? What is the official coordinate contract for HKWorkoutRoute locations for apps working with GCJ-02 data in mainland China? Is there a supported way to opt out, and what decides whether a given route enters this state? Which component owns the conversion — Health/Fitness route rendering or MapKit? I am deliberately not pre-converting the first ~49 points: that would store mixed datums in HealthKit, wrong for the Health app itself, for exports, for every third-party reader, and wrong for all of them the moment this is fixed. Happy to share the one-tap sample project, the exported JSON with all 2794 stored CLLocation values, the original .fit, and the probe E/F/G screenshots — reply here and I'll attach them.
Replies
1
Boosts
0
Views
94
Activity
6d
Can watchOS apps access Apple-generated sleep stages in real time for a smart alarm?
I’m evaluating a native watchOS smart-alarm app and would like to clarify whether public APIs support its core requirement before building a prototype. The app would wake the user during a 20–30-minute window before their selected alarm time, using Apple Watch’s own sleep-stage classifications available through HealthKit’s sleepAnalysis category: Core, Deep, REM, and Awake. I have reviewed HKCategoryValueSleepAnalysis, HKAnchoredObjectQuery, HKObserverQuery, background delivery, and WKExtendedRuntimeSession’s Smart Alarm mode. However, I haven’t found documentation establishing when Apple-generated sleep-stage samples become available during an ongoing sleep session. Could you clarify: Are Apple-generated sleep-stage samples written to the Watch’s local HealthKit store during sleep, or only after the sleep session ends or subsequent processing? If available during sleep, is there any documented update cadence or latency that would make them suitable for a smart alarm? Should the latest sample be treated only as a retrospective classification rather than the current sleep stage? Can an app query these samples during a Smart Alarm extended runtime session while the Watch is worn and unlocked, with its display off and Sleep Focus enabled? Are there relevant execution or data-access restrictions? If this use case is unsupported, is there any public API that exposes Apple’s current sleep-stage estimate? If not, which Feedback Assistant category is appropriate for requesting this capability? The intended approach queries HealthKit directly on Apple Watch, without depending on Watch-to-iPhone synchronization, and retains a fixed latest wake-up time as a fallback. This is an API feasibility question, not a reproduced bug. I haven’t yet built or tested a prototype. Thank you.
Replies
2
Boosts
0
Views
245
Activity
1w
Extended Runtime API - Health Monitoring
In the WWDC 2019 session "Extended Runtime for WatchOS apps" the video talks about an entitlement being required to use the HR sensor judiciously in the background. It provides a link to request the entitlement which no longer works: http://developer.apple.com/contect/request/health-monitoring The session video is also quite hard to find these days. Does anyone know why this is the case? Is the API and entitlement still available? Is there a supported way to run, even periodically, in the background on the Watch app (ignoring the background observer route which is known to be unreliable) and access existing HR sensor data
Replies
16
Boosts
1
Views
2.9k
Activity
1w
iOS 27 Health permissions: a reckoning is coming
iOS 27 adds a second stage to HealthKit read authorization. After picking data types, the user chooses "Past 30 Days and Future Data" or "All Recorded Data and Future Data", with Allow disabled until one is selected. Every user of every health app now makes this call, in the first seconds of onboarding, with no real context about what the app needs. I don't think the scale of this has landed yet. A meaningful share of users will pick 30 days. multi-year health trends, month to month comparisons, all-time records: with 30 days these features don't get worse, they stop existing. And it breaks silently. The user sees empty charts and a app that doesn't do what the screenshots promised. They won't connect that to a sheet they tapped through on day one — they'll connect it to the app. That's the reckoning: a wave of one-star reviews and support mail for a decision the developer never saw and can't inspect. Because we can't inspect it .authorizationStatus(for:) deliberately hides read authorization and getRequestStatusForAuthorization only says whether prompting would show UI, so a 30-day grant and a genuinely new Apple Watch user look identical from the query layer. A callback when Health permissions change for a type — even without disclosing the new state — would go a long way here. And we can't route users to the fix. UIApplication.openSettingsURLString opens the app's own Settings page, which has no Health section. The real control sits at Settings › Privacy & Security › Health › — four levels deep, unreachable from any public API. My suggestion is a URL constant scoped to the calling app, the way openNotificationSettingsURLString (iOS 15.4+) and openDefaultApplicationsSettingsURLString (iOS 18.3+) already work. But that's just my idea; if there's a better mitigation, or something already planned, I'd like to hear it. Worth saying the privacy gain looks thin either way: the app keeps all future data indefinitely, so a 30-day grant becomes a full-history grant in thirty days for anyone who keeps the app. The window limits what's readable today, not what accumulates. iOS 27 release is approaching... I think this will cause problems 😞 Filed as FB24398048 and FB24398031
Replies
2
Boosts
0
Views
1.2k
Activity
1w
Intermittent missing historical step counts from HKStatisticsCollectionQuery on iOS 27 beta
Hello, We received a customer report about intermittent missing historical step-count data when using HKStatisticsCollectionQuery on iOS 27 beta. When the query was executed on August 16, only the most recent two days—August 16 and August 15—returned correct step counts. Earlier dates returned nil from sumQuantity() and were consequently treated as zero. However, queries executed on August 14 and August 18 returned the expected data. Therefore, the problem appears to be intermittent rather than consistently reproducible. The customer confirmed that all affected historical step counts were visible in the Apple Health app, including the dates returned as zero by our query. We have not received the same type of customer report from devices running iOS 26 or earlier. Here is a simplified version of our query: guard let stepType = HKObjectType.quantityType( forIdentifier: .stepCount ) else { return } var calendar = Calendar(identifier: .gregorian) calendar.timeZone = TimeZone(identifier: "Asia/Seoul")! let queryStartDate = calendar.startOfDay(for: parsedStartDate) let tomorrow = calendar.date(byAdding: .day, value: 1, to: Date())! let queryEndDate = calendar.startOfDay(for: tomorrow) let datePredicate = HKQuery.predicateForSamples( withStart: queryStartDate, end: queryEndDate, options: .strictStartDate ) let nonUserEnteredPredicate = HKQuery.predicateForObjects( withMetadataKey: HKMetadataKeyWasUserEntered, operatorType: .notEqualTo, value: NSNumber(value: true) ) let predicate = NSCompoundPredicate( andPredicateWithSubpredicates: [ datePredicate, nonUserEnteredPredicate ] ) let anchorDate = calendar.startOfDay(for: Date()) var interval = DateComponents() interval.day = 1 let query = HKStatisticsCollectionQuery( quantityType: stepType, quantitySamplePredicate: predicate, options: .cumulativeSum, anchorDate: anchorDate, intervalComponents: interval ) query.initialResultsHandler = { _, results, error in guard let results, error == nil else { print("Query error: \(String(describing: error))") return } results.enumerateStatistics( from: queryStartDate, to: queryEndDate ) { statistics, _ in let steps = statistics .sumQuantity()? .doubleValue(for: .count()) ?? 0 print(statistics.startDate, statistics.endDate, steps) } } healthStore.execute(query) Observed behavior Query executed on August 14: historical step counts returned correctly Query executed on August 16: August 16 and August 15 returned correctly August 14 and earlier returned nil from sumQuantity() Query executed on August 18: historical step counts returned correctly again No query error was reported All step counts remained visible in the customer's Apple Health app Expected behavior The query should consistently return cumulative daily step counts when matching HealthKit samples exist and are visible in the Health app. Because this was reported through customer support, we do not currently know the exact iOS 27 beta build number. We are also unable to reproduce it consistently on our own test devices. Questions Is there a known intermittent issue with historical .stepCount queries on iOS 27 beta? Can HealthKit temporarily return incomplete statistics while data is being indexed, synchronized, or migrated? Is there a recommended way to detect that the returned statistics are temporarily incomplete? Should applications retry the query when older statistics unexpectedly return nil without an error? We have not received reports of this behavior from customers using iOS 26 or earlier. Thank you.
Replies
3
Boosts
0
Views
945
Activity
1w
watchOS 27: Environmental Audio Exposure sampling became extremely sparse
After updating my Apple Watch Series 10 to the public release of watchOS 27, Environmental Sound Level measurements became extremely sparse. Before watchOS 27, with Environmental Sound Measurements enabled, my watch recorded environmental sound data approximately every 30 seconds and the coverage was nearly continuous throughout the day. After updating the same Apple Watch to watchOS 27, the behavior changed significantly: Environmental Sound Level samples are much less frequent Large gaps appear between measurements Overall daily temporal coverage is dramatically reduced The same change is visible both in the Health app and through HealthKit using HKQuantityTypeIdentifier.environmentalAudioExposure No relevant settings were changed, and Environmental Sound Measurements are still enabled. This is important for apps that use Environmental Audio Exposure data for time-based analysis. In my case, I use this data for sleep and nap environment analysis. With the much sparser sampling on watchOS 27, it is difficult to reliably evaluate the acoustic environment during a specific sleep period. I have also seen other watchOS 27 users reporting similar behavior: https://www.reddit.com/r/watchOSBeta/comments/1wjrdaq/watchos_27_broke_the_noise_monitoring_app/ I submitted a Feedback Assistant report: FB24837491 Has anyone else observed the same change on watchOS 27? I’m especially interested in whether this is: an intentional change to the sampling or aggregation strategy, a HealthKit write-frequency change, or a regression in watchOS 27. If anyone has compared HKQuantitySample.startDate, endDate, sample duration, and sample interval before and after the watchOS 27 update, that data would be very useful for comparison.
Replies
2
Boosts
1
Views
440
Activity
2w
Is frequent heart-rate delivery during a paused Mind & Body workout supported?
I am developing a watchOS wellness app with explicitly user-started monitoring during ordinary daily activities. The goal is timely physiological-change check-ins over an approximately eight-to-ten-hour monitoring period, including when the display is off. This is not exercise monitoring or a diagnostic use case. The relevant API sequence is: Create HKWorkoutConfiguration with activityType .mindAndBody and locationType .unknown. Create HKWorkoutSession, its associated HKLiveWorkoutBuilder and HKLiveWorkoutDataSource; set the session and builder delegates. Restrict builder collection to heart rate, then call startActivity(with:) and beginCollection(withStart:). After receiving initial live HR, call HKWorkoutSession.pause(). Receive .heartRate through workoutBuilder(_:didCollectDataOf:) and read statistics(for:), mostRecentQuantity() and mostRecentQuantityDateInterval(). When the user ends monitoring, end collection and discard the workout rather than save it. In development tests on Apple Watch hardware, HR callbacks have continued for hours after pausing, including while backgrounded, with roughly five-second average intervals. Some tests have shown gaps. I do not assume that observing this behavior establishes a supported API guarantee. Is frequent live-builder HR delivery in the paused state officially supported, or is this behavior an implementation detail that an app must not rely on? Is there a supported watchOS API or architecture for this non-exercise monitoring goal, and what are its HR-delivery/background-runtime limits? The app uses HealthKit and HealthKit background-delivery entitlements and the workout-processing background mode. I would also appreciate clarification about possible Activity-ring or energy-calculation effects when the workout is paused and ultimately discarded.I am developing a watchOS wellness app with explicitly user-started monitoring during ordinary daily activities. The goal is timely physiological-change check-ins over an approximately eight-to-ten-hour monitoring period, including when the display is off. This is not exercise monitoring or a diagnostic use case. The relevant API sequence is: Create HKWorkoutConfiguration with activityType .mindAndBody and locationType .unknown. Create HKWorkoutSession, its associated HKLiveWorkoutBuilder and HKLiveWorkoutDataSource; set the session and builder delegates. Restrict builder collection to heart rate, then call startActivity(with:) and beginCollection(withStart:). After receiving initial live HR, call HKWorkoutSession.pause(). Receive .heartRate through workoutBuilder(_:didCollectDataOf:) and read statistics(for:), mostRecentQuantity() and mostRecentQuantityDateInterval(). When the user ends monitoring, end collection and discard the workout rather than save it. In development tests on Apple Watch hardware, HR callbacks have continued for hours after pausing, including while backgrounded, with roughly five-second average intervals. Some tests have shown gaps. I do not assume that observing this behavior establishes a supported API guarantee. Is frequent live-builder HR delivery in the paused state officially supported, or is this behavior an implementation detail that an app must not rely on? Is there a supported watchOS API or architecture for this non-exercise monitoring goal, and what are its HR-delivery/background-runtime limits? The app uses HealthKit and HealthKit background-delivery entitlements and the workout-processing background mode. I would also appreciate clarification about possible Activity-ring or energy-calculation effects when the workout is paused and ultimately discarded.
Replies
0
Boosts
0
Views
54
Activity
2w
HealthKit: Historical pool workout locations for a personal swimming map
Hello Apple Developer Relations and the HealthKit team, I'm a hobbyist developer and recreational swimmer building a personal app to make better use of my own Apple Watch workout data. My goal is training management, post-workout reviews, and long-term summaries of my swimming history. Design goal I would like to create a global map of places where I have swum, similar to the map view in Apple Photos: When zoomed out, group locations by country or region and show the number of distinct swimming places, rather than the number of workouts. When zoomed in, reveal individual places and their associated workouts. Venue or water-body names could be added later where they can be reliably identified. For pool swimming, a single location point is sufficient. A route is not required. For open-water swimming, show the place first, then reveal an individual workout's route when selected. Group repeated visits to the same place while retaining each workout for review. Data requirement The key requirement is read-only access to a location associated with an existing workout, including historical pool workouts recorded using Apple's Workout app. A coordinate linked to the workout would be enough to begin with; I am not expecting HealthKit to identify or name the venue. What I have observed In on-device tests, I can read routes for open-water swimming workouts. For the historical pool workouts I checked, no route was returned, and I did not find usable location coordinates in the public workout, activity, event, or route metadata I inspected. However, Apple Fitness displays a map point for historical pool workouts. The absence of a route therefore does not establish the absence of a recorded location. I have read the DTS response explaining that there is currently no public API for third-party access to indoor workout locations: https://developer.apple.com/forums/thread/827939 Current obstacle Without a supported way to obtain these historical points, the app cannot automatically build a useful map of past pool visits. Recording locations from now on or asking users to assign old workouts manually would not recover the existing history. A computer-backup extraction workflow also would not meet the intended standalone iPhone app experience. Questions and enhancement request Beyond the current HealthKit APIs, is there any supported, user-initiated export or import path that preserves historical indoor workout coordinates and their association with the workout? If there is no supported path today, could Apple consider read-only access to historical workout locations through HealthKit, with explicit user authorization and clear handling of missing or approximate locations? I understand that a formal enhancement request belongs in Feedback Assistant. I am sharing this concrete design and data requirement here to clarify the use case and ask whether a supported alternative already exists. Thank you for considering this request.
Replies
0
Boosts
0
Views
116
Activity
4w
Export PDF from Apple Health app in iOS 27.2 beta
We depend on the Export PDF button in previous Apple Health apps and it seems to have disappeared in 27.2 beta. Merging FHIR results from multiple hospitals, pharmacies and other patient portals is complex. Apple does an excellent job of merging, categorizing, and displaying this information in the app and it used to generate a great human-readable PDF export. Exporting individual categories as a PDF would be fussy and unreliable for a typical user. Is this regression in the beta an oversight or a strategic shift on the part of Apple to deprive users of an easy to use combined patient summary?
Replies
1
Boosts
0
Views
163
Activity
4w
HKStatisticsCollectionQueryDescriptor intermittently returns no data for certain date ranges on iOS 27
We are seeing inconsistent results from HKStatisticsCollectionQueryDescriptor on iOS 27. Using the same quantity type, statistics options, anchor date, interval components, and predicate configuration, some date ranges return the expected statistics, while other ranges unexpectedly return empty results or buckets with no quantity. The affected ranges do contain HealthKit samples: HKSampleQueryDescriptor finds samples in the same date range. HKStatisticsQueryDescriptor returns the expected value when run separately for an affected bucket. HKStatisticsCollectionQueryDescriptor returns no quantity for that same bucket. Slightly expanding or shifting the date range may cause the collection query to return data again. A simplified version of the query looks like this: let datePredicate = HKQuery.predicateForSamples( withStart: startDate, end: endDate, options: .strictStartDate ) let descriptor = HKStatisticsCollectionQueryDescriptor( predicate: .quantitySample( type: quantityType, predicate: datePredicate ), options: .cumulativeSum, anchorDate: anchorDate, intervalComponents: DateComponents(day: 1) ) let collection = try await descriptor.result(for: healthStore) collection.enumerateStatistics(from: startDate, to: endDate) { statistics, _ in let quantity = statistics.sumQuantity() print(statistics.startDate, quantity as Any) } Expected behavior Every interval containing matching samples should return the corresponding statistics, regardless of the overall requested date range. Actual behavior Some date ranges produce missing or empty buckets even though matching samples exist and an individual HKStatisticsQueryDescriptor can calculate the expected value. Changing only the date range can make the data appear or disappear. The samples are visible to the app in the affected range, so this does not appear to be explained solely by iOS 27’s Limited History authorization. This behavior was not observed with the same query flow on earlier iOS versions. Is this a known regression in HKStatisticsCollectionQueryDescriptor on iOS 27, or has the expected date-range or predicate behavior changed?
Replies
3
Boosts
3
Views
1.1k
Activity
Oct ’26
Unable to invalidate interval: no data source available error when fetching steps using HKStatisticsCollectionQuery
While attempting to read a user’s daily step history spanning backward to the last 7 days, a small but consistent subset of users encounter Error Code 3 with the underlying error description: Error Code 3 "Unable to invalidate interval: no data source available." When this error occurs, we are entirely unable to read their step history. We have received ~10 direct user reports of this within the last couple of weeks.
Replies
15
Boosts
2
Views
2.3k
Activity
Sep ’26
Apple Watch Health data stopped syncing to iPhone — FB24923176
Health and Workout data stopped syncing from my Apple Watch to my iPhone on 21 September while both devices were on the public releases. The Watch continues recording the data and the missing data remains on the Watch. Activity Sharing also continues to work. I’ve since installed the matching iOS/watchOS developer betas in an attempt to resolve the pre-existing issue, but it remains. And now I cannot get assistance via the usual Apple Support route. I’ve submitted a Feedback Assistant report with both iOS and watchOS sysdiagnoses: FB24923176. Multiple users are also reporting this issue here - https://www.reddit.com/r/AppleWatch/comments/1whu0at/apple_watch_workoutshealth_data_stopped_syncing/ Could someone advise whether this can be reviewed by the appropriate HealthKit/watchOS team? I am deliberately avoiding unpairing the Watch because the unsynced data is currently only stored on the Watch. Thanks so much!
Replies
0
Boosts
0
Views
334
Activity
Sep ’26
SensorKit PPG Access and Optical Sensor Specifications for Apple Watch Series 9 Research
We are an interdisciplinary research team involving Gazipaşa Science High School and Akdeniz University in Türkiye, including student researchers, a project advisor, and a medical researcher. We are conducting a non-commercial scientific research project within the TÜBİTAK 2204-A High School Students Research Projects Competition. As part of the project, we are developing an experimental wrist-based optical monitoring system. We plan to use an Apple Watch Series 9 (A2980, Part Number MR9A3TU/A) as a comparative benchmark during the development and evaluation of our system. In particular, we are interested in accessing Apple Watch photoplethysmography (PPG) data through SensorKit. We intend to use these data to support the iterative development of our optical monitoring system and to evaluate and report how modifications to our system affect its signal characteristics and performance relative to an established commercial wearable optical sensing platform. Apple Watch measurements will be used for comparative research and system evaluation, rather than as a clinical reference or diagnostic measurement. We would therefore appreciate guidance on the appropriate procedure for obtaining SensorKit access and the required entitlement for Apple Watch PPG data for this type of scientific research. To perform a scientifically meaningful comparison, we also need reliable technical information about the optical sensing system of the Apple Watch used in our study. However, we have been unable to find an authoritative and citable Apple source specifying the wavelengths or wavelength ranges of the optical emitters used in the Apple Watch Series 9 (A2980). Could you please direct us to any official Apple documentation, publication, technical specification, or other authoritative resource containing this information? If the exact specifications are not publicly available, we would appreciate guidance on whether such information can be provided for academic research purposes. We would also appreciate recommendations for the appropriate Apple technical support channel, Developer Forum, research contact, or other point of contact for further questions that may arise during the development and research process. Thank you for your time and guidance.
Replies
1
Boosts
0
Views
297
Activity
Sep ’26
Health sleep score incorrect in 27.2
I have 27.2 developer beta running on my iPhone Air and Watch Ultra 4. My wife has an 18 Pro and also Ultra 4 but hers are both running the current public release versions of iOS 27 and watchOS 27. After 2 nights with the Ultra 4's, her sleep score is reporting accurate. Mine is way off. For example, last night we went to bed around 10 PM and woke up at 7 AM. Her scores were in the 90's with 7:36 hours of sleep. Mine is in the 40's with 4:20 hours of sleep. We both slept the same/great last night. Similar results for the night before - hers is accurate; mine are way off.
Replies
1
Boosts
0
Views
171
Activity
Sep ’26
Maintaining a Core Bluetooth connection on watchOS for the duration of an HKWorkoutSession
I have a watchOS app that records workouts on a piece of Bluetooth LE fitness equipment. It runs an HKWorkoutSession and, for the length of that session, stays connected to the machine and subscribed to a characteristic that reports step data once a second. Each notification is recorded into the workout's HKLiveWorkoutBuilder. The connection needs to last as long as the workout — typically 20–60 minutes. The watch app declares both: WKBackgroundModes = workout-processing UIBackgroundModes = bluetooth-central This works indefinitely while the app is in the foreground. When the app leaves the foreground — the user lowers their wrist or goes to the watch face — the peripheral disconnects after roughly three minutes, and the workout loses the rest of its data. What we have been able to establish from logs at the moment of the disconnect: The app is not suspended. Notifications arrive at a steady 1 Hz with no gaps right up to the disconnect (271 and 272 consecutive notifications in two separate cases), so the workout session is keeping the app running as expected. centralManager.state is .poweredOn. centralManager(_:didDisconnectPeripheral:error:) is called with error == nil, and the peripheral's state is .disconnected. Nothing in our code calls cancelPeripheralConnection at that point; our own teardown runs afterwards, in response to the disconnect. The user is still using the machine, and the machine is still notifying. Reproducible: two captures roughly three minutes and twenty seconds after the app backgrounded. I understand from Get timely alerts from Bluetooth devices on watchOS (WWDC22) that background Bluetooth on watchOS is intended for timely alerts, with a limited number of background runtime opportunities, and that periodic data collection should use Background App Refresh instead. Our data arrives once a second for the whole workout, so I assume we are well outside what that mode is budgeted for, and that the disconnect is the system reclaiming the link. My questions: Does a running HKWorkoutSession grant any exemption from the background Bluetooth limits? workout-processing clearly keeps the app executing — we receive notifications for minutes after backgrounding — but the connection is still torn down. Is Bluetooth's background budget independent of the workout runtime, and is that the intended behaviour? Is there a supported way to hold a BLE connection for the duration of a workout session? Reading a fitness machine's telemetry for an entire workout seems like a mainstream use of both frameworks together, but I cannot find a configuration that survives the app leaving the foreground. Would a longer connection interval change this? The session recommends at least 150 ms. If the disconnect is driven by connection-event volume rather than notification count, a slower interval or a lower update rate may be the answer — and if so, is there a documented threshold to aim for? error == nil on disconnect. The documentation says a nil error means the disconnect was requested locally via cancelPeripheralConnection, which we do not call here. Should a system-initiated reclaim of the link be reported this way, or is there a more specific error we should be looking for? We now log the error on peripheral(_:didUpdateValueFor:error:) to catch LeGattNearBackgroundNotificationLimit and LeGattExceededBackgroundNotificationLimit, but have not yet observed either before a disconnect. Is there any entitlement path for this? We are aware of com.apple.developer.bluetooth-central-background and that it is limited to continuous glucose monitoring. Is there an equivalent route for fitness equipment, or is foreground-only the expected design for this class of app? If continuous background Bluetooth is simply not available here, I would like to know that clearly, so I can design around the disconnect — reconnecting mid-workout rather than treating a dropped link as the end of the session.
Replies
0
Boosts
0
Views
257
Activity
Sep ’26
Measuring continuous heart rate without using HKWorkoutSession?
I'm writing a Watch app where we have an in-built protocol for measuring resting heart rate. The user taps start and the heart rate is measured for 30 minutes while they're lying down. It works well, but because I'm using HKWorkoutSession to do this, the green exercise ring is advancing by 30 minutes even though the user is not exercising. So, any way to get continuous heart rate measurements without using HKWorkoutSession?
Replies
1
Boosts
0
Views
229
Activity
Sep ’26
WatchOS HealthKit HKObserverQuery crashes in background
I have a watchOS app with a connected iOS app using Swift and SwiftUI. The watchOS app should read heart rate date in the background using HKOberserQuery and enableBackgroundDelivery(), send the data to the iPhone app via WCSession. The iPhone app then sends the data to a Firebase project. The issue I am facing now it that the app with the HKObserverQuery works fine when the app is in the foreground, but when the app runs in the background, the observer query gets triggered for the first time (after one hour), but then always get terminated from the watchdog timeout with the following error message: CSLHandleBackgroundHealthKitQueryAction scene-create watchdog transgression: app<app.nanacare.nanacare.nanaCareHealthSync.watchkitapp((null))>:14451 exhausted real (wall clock) time allowance of 15.00 seconds I am using Xcode 16.3 on MacOS 15.4 The App is running on iOS 18.4 and watchOS 11.4 What is the reason for this this issue? I only do a simple SampleQuery to fetch the latest heart rate data inside the HKObserverQuery and then call the completionHandler. The query itself takes less than one second. Or is there a better approach to read continuously heart rate data from healthKit in the background on watchOS? I don't have an active workout session, and I don't need all heart rate data. Once every 15 minutes or so would be enough.
Replies
13
Boosts
1
Views
2.1k
Activity
Aug ’26