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

How can Core Motion accelerometer sample age be reliably verified on iOS?
Hello, I’m developing an iPhone safety application for people working alone outdoors. The app uses CMMotionManager accelerometer updates to detect prolonged inactivity while the phone is worn on the body, including when the screen is locked. In a physical iPhone test, we recorded 7,232 samples over approximately 12 minutes, including 6,925 samples tagged as background. Delivery intervals were stable. However, we cannot establish a documented relationship between CMAccelerometerData.timestamp and a host monotonic clock that would let us reliably determine each sample’s acquisition-to-consumption age. My questions are: Is CMAccelerometerData.timestamp guaranteed to be directly comparable to ProcessInfo.systemUptime or mach_absolute_time? How does this relationship behave across device sleep/wake and app suspension/resumption? Can Core Motion deliver previously buffered accelerometer samples after the app resumes? Is there a supported way to calculate or conservatively bound the actual age of an individual accelerometer sample? Our current implementation deliberately treats samples as unverified until their freshness can be established. We do not interpret stable callback intervals as proof of fresh measurements. Any guidance from Apple engineers or developers familiar with Core Motion timestamp semantics would be greatly appreciated. Thank you!
0
0
51
23h
CMMotionActivityManager: past activities move in time between queries (watchOS 27, Apple Watch Ultra 4)
When I query the same past period with CMMotionActivityManager.queryActivityStarting(from:to:to:) at two different times, the second result contains the same activities, but their startDate values are earlier. Setup Apple Watch Ultra 4 (Watch8,1), watchOS 27.0.1 My app reads the activity history a few minutes after it happens and stores it. Later it queries the same period again and compares the results. What I see The activity types and durations do not change. Whole blocks of history move back in time by a constant offset. Example from today's query, compared with the stored values: Period of the dataOffsetNov 8, 12:47 – 19:55−155 sNov 8, 19:57 – Nov 9, 17:18−95 sNov 9, 17:19 – now0 sYesterday at 17:19, the same Nov 8 evening data had an offset of 0 s. So the offset changes over time, not only with the age of the data. New steps add up: when a step occurs, all older history moves back by the same amount. Earlier I saw offsets of −60 s, −123 s, −177 s and −340 s. The stored values match HealthKit workout start and end times within about 8 s. The re-queried values do not (for example −52 s at the start of a run). timestamp of these activities is equal to startDate (seconds since 2001), so it does not help to match them. I did not see this on Apple Watch Ultra 3 with watchOS 27, but I have only one comparison from that watch. Questions Is startDate of a past CMMotionActivity expected to stay the same? If not, which event changes it, and is there a way to detect it? What is the recommended way to get stable times from the activity history? I log every query on the watch (all activities plus clock and battery state every 30 minutes), so I can share data or a sysdiagnose. I will also file a Feedback.
0
0
32
1d
Sending a user-approved summary derived from HealthKit data to a third-party AI service (Guideline 5.1.3(i), DPLA 3.3.3(H))?
An optional coaching feature in my planned app would, after explicit opt-in, send a short text summary (for example sleep duration or heart rate variability over the last week) to a third-party AI service to generate advice for that same user. The data is not used for advertising, marketing or data mining. Guideline 5.1.3(i) allows disclosure of HealthKit-derived data only "for improving health management, or for the purpose of health research, and then only with permission", and DPLA 3.3.3(H) allows disclosure to a third party only with prior express consent and only to provide health, motion or fitness services. Is a per-user coaching feature like this within what 5.1.3(i) and 3.3.3(H) permit? Does it matter whether the summarised values were entered manually (and stored in HealthKit) or measured by a device? I understand this is not a pre-approval; I would like to know how the rule is meant to be read. Thank you.
0
0
258
2d
Guideline 5.1.3(ii) and DPLA 3.3.3(D): private CloudKit for meal logs and workout logs (no HealthKit values)?
I am planning an iOS app for strength training, nutrition and sleep. Before I build the data layer I would like to understand how Apple reads the following rules. Planned design: Body measurements and sleep values live in HealthKit only and are never written to iCloud or CloudKit. Training sessions and meal entries (food, calories, macronutrients, entered manually or by barcode scan) are stored on the device and in the user's private CloudKit database. Nothing is stored on our own servers. The app also caches packaged food products the user has scanned (name, ingredients, allergens, nutrition facts from the public Open Food Facts database) in the same private CloudKit database. Guideline 5.1.3(ii) says apps "may not store personal health information in iCloud", and DPLA 3.3.3(D) restricts using iCloud or CloudKit for "sensitive, individually-identifiable health information" unless Apple permits it in writing. Questions: Does a meal log or a product cache in the user's private CloudKit database count as "personal health information" in this sense, as long as no HealthKit values are stored there? Is the answer different if the private CloudKit data is end-to-end encrypted (encryptedValues)? I understand that App Review cannot pre-approve an app. I am only asking how the rule is meant to be read. Thank you.
0
0
242
2d
HealthKit Active Energy background delivery only arrives when app enters foreground
I’m investigating delayed HealthKit background delivery in an iPhone calorie-tracking app installed through TestFlight. The app reads activeEnergyBurned and submits a local notification with a custom sound for every newly accumulated 20 kcal. The intended behavior is passive: the user walks normally without explicitly starting a workout. Current behavior: Rewards appear after opening the app. Unlocking the phone to the iPhone Home Screen does not trigger the accumulated rewards. The app is backgrounded, not force-quit. A separate local notification scheduled 10 seconds ahead successfully displays and plays its custom sound while the phone is locked. Implementation: An HKObserverQuery for activeEnergyBurned, with predicate nil, is registered during application(_:didFinishLaunchingWithOptions:). Background delivery is requested with frequency .immediate. The installed TestFlight app has the HealthKit and HealthKit background-delivery entitlements. With valid locally stored access, Health processing does not wait for a StoreKit subscription query. In the captured trace, observer callbacks complete promptly and healthd reports no outstanding launches afterward. Recorded test on November 7, 2026 (device-log times, UTC−07:00): Around 07:03, I manually added 40 kcal in Apple Health. At 07:03:42, Health received an added sample. healthd scheduled the next Active Energy background launch for 08:03:14, approximately one hour after our previous observer completion. At 07:05:42, I unlocked to the Home Screen. Protected Health data became available, but no corresponding observer callback reached our app. At 07:08:40, I opened our app. Its observer callback arrived immediately, and two reward notification requests were accepted without error. Earlier development installations appeared to deliver accumulated rewards upon unlocking to the Home Screen, even after the debugger had disconnected. Subscription integration occurred between those versions, but we have not established the cause of the difference. My questions: Is an approximately one-hour interval expected for activeEnergyBurned on iPhone despite requesting .immediate? Can foreground observer completions advance the next permitted background delivery time? Is there a supported way to receive pending Active Energy updates after unlocking, without opening the app or starting an HKWorkoutSession? I can provide targeted implementation details and additional relevant log excerpts if needed. Thank you.
0
0
66
3d
Can an iPhone app receive AirPods Pro 3 heart-rate updates once per second through a supported API?
I’m building an iPhone app that aligns live heart-rate readings with a video recording. I’m looking for a supported way to receive a fresh AirPods Pro 3 BPM estimate about once per second during an active session. I tested with an iPhone 16 running iOS 27.2 and AirPods Pro 3. A minimal test app starts an HKWorkoutSession on the iPhone, collects heart rate with HKLiveWorkoutBuilder, and records the source timestamp of each distinct reading. With both .other / .indoor and .running / .outdoor, the median spacing between readings was about five seconds. Querying HealthKit afterward returned the same in-take readings. Is that cadence expected for third-party apps? Is there a documented API, workout configuration, or capability that Apple makes available to third-party developers for receiving fresh AirPods Pro 3 BPM estimates at about 1 Hz? My requirement is for a new estimate from the AirPods at that cadence. Polling more frequently or interpolating between readings would not meet it.
3
0
66
6d
Is CMSensorRecorder accelerometer recording and retrieval supported while Apple Watch is charging?
On an Apple Watch Series 4-5, our app receives no recorded accelerometer samples during charging. Repeating the query for the same interval after disconnecting the charger also returns nil. Recording without the charger produces samples. An HKWorkoutSession remains running during the unsuccessful test, and live motion collection works while charging. Is this expected behavior or a known limitation? If supported, what conditions must be met?
1
0
63
1w
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.
3
0
120
1w
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
211
1w
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
423
2w
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
131
2w
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
285
2w
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
3.0k
2w
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.3k
2w
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
991
3w
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
468
3w
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
70
3w
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
125
Oct ’26
How can Core Motion accelerometer sample age be reliably verified on iOS?
Hello, I’m developing an iPhone safety application for people working alone outdoors. The app uses CMMotionManager accelerometer updates to detect prolonged inactivity while the phone is worn on the body, including when the screen is locked. In a physical iPhone test, we recorded 7,232 samples over approximately 12 minutes, including 6,925 samples tagged as background. Delivery intervals were stable. However, we cannot establish a documented relationship between CMAccelerometerData.timestamp and a host monotonic clock that would let us reliably determine each sample’s acquisition-to-consumption age. My questions are: Is CMAccelerometerData.timestamp guaranteed to be directly comparable to ProcessInfo.systemUptime or mach_absolute_time? How does this relationship behave across device sleep/wake and app suspension/resumption? Can Core Motion deliver previously buffered accelerometer samples after the app resumes? Is there a supported way to calculate or conservatively bound the actual age of an individual accelerometer sample? Our current implementation deliberately treats samples as unverified until their freshness can be established. We do not interpret stable callback intervals as proof of fresh measurements. Any guidance from Apple engineers or developers familiar with Core Motion timestamp semantics would be greatly appreciated. Thank you!
Replies
0
Boosts
0
Views
51
Activity
23h
CMMotionActivityManager: past activities move in time between queries (watchOS 27, Apple Watch Ultra 4)
When I query the same past period with CMMotionActivityManager.queryActivityStarting(from:to:to:) at two different times, the second result contains the same activities, but their startDate values are earlier. Setup Apple Watch Ultra 4 (Watch8,1), watchOS 27.0.1 My app reads the activity history a few minutes after it happens and stores it. Later it queries the same period again and compares the results. What I see The activity types and durations do not change. Whole blocks of history move back in time by a constant offset. Example from today's query, compared with the stored values: Period of the dataOffsetNov 8, 12:47 – 19:55−155 sNov 8, 19:57 – Nov 9, 17:18−95 sNov 9, 17:19 – now0 sYesterday at 17:19, the same Nov 8 evening data had an offset of 0 s. So the offset changes over time, not only with the age of the data. New steps add up: when a step occurs, all older history moves back by the same amount. Earlier I saw offsets of −60 s, −123 s, −177 s and −340 s. The stored values match HealthKit workout start and end times within about 8 s. The re-queried values do not (for example −52 s at the start of a run). timestamp of these activities is equal to startDate (seconds since 2001), so it does not help to match them. I did not see this on Apple Watch Ultra 3 with watchOS 27, but I have only one comparison from that watch. Questions Is startDate of a past CMMotionActivity expected to stay the same? If not, which event changes it, and is there a way to detect it? What is the recommended way to get stable times from the activity history? I log every query on the watch (all activities plus clock and battery state every 30 minutes), so I can share data or a sysdiagnose. I will also file a Feedback.
Replies
0
Boosts
0
Views
32
Activity
1d
Sending a user-approved summary derived from HealthKit data to a third-party AI service (Guideline 5.1.3(i), DPLA 3.3.3(H))?
An optional coaching feature in my planned app would, after explicit opt-in, send a short text summary (for example sleep duration or heart rate variability over the last week) to a third-party AI service to generate advice for that same user. The data is not used for advertising, marketing or data mining. Guideline 5.1.3(i) allows disclosure of HealthKit-derived data only "for improving health management, or for the purpose of health research, and then only with permission", and DPLA 3.3.3(H) allows disclosure to a third party only with prior express consent and only to provide health, motion or fitness services. Is a per-user coaching feature like this within what 5.1.3(i) and 3.3.3(H) permit? Does it matter whether the summarised values were entered manually (and stored in HealthKit) or measured by a device? I understand this is not a pre-approval; I would like to know how the rule is meant to be read. Thank you.
Replies
0
Boosts
0
Views
258
Activity
2d
Guideline 5.1.3(ii) and DPLA 3.3.3(D): private CloudKit for meal logs and workout logs (no HealthKit values)?
I am planning an iOS app for strength training, nutrition and sleep. Before I build the data layer I would like to understand how Apple reads the following rules. Planned design: Body measurements and sleep values live in HealthKit only and are never written to iCloud or CloudKit. Training sessions and meal entries (food, calories, macronutrients, entered manually or by barcode scan) are stored on the device and in the user's private CloudKit database. Nothing is stored on our own servers. The app also caches packaged food products the user has scanned (name, ingredients, allergens, nutrition facts from the public Open Food Facts database) in the same private CloudKit database. Guideline 5.1.3(ii) says apps "may not store personal health information in iCloud", and DPLA 3.3.3(D) restricts using iCloud or CloudKit for "sensitive, individually-identifiable health information" unless Apple permits it in writing. Questions: Does a meal log or a product cache in the user's private CloudKit database count as "personal health information" in this sense, as long as no HealthKit values are stored there? Is the answer different if the private CloudKit data is end-to-end encrypted (encryptedValues)? I understand that App Review cannot pre-approve an app. I am only asking how the rule is meant to be read. Thank you.
Replies
0
Boosts
0
Views
242
Activity
2d
HealthKit Active Energy background delivery only arrives when app enters foreground
I’m investigating delayed HealthKit background delivery in an iPhone calorie-tracking app installed through TestFlight. The app reads activeEnergyBurned and submits a local notification with a custom sound for every newly accumulated 20 kcal. The intended behavior is passive: the user walks normally without explicitly starting a workout. Current behavior: Rewards appear after opening the app. Unlocking the phone to the iPhone Home Screen does not trigger the accumulated rewards. The app is backgrounded, not force-quit. A separate local notification scheduled 10 seconds ahead successfully displays and plays its custom sound while the phone is locked. Implementation: An HKObserverQuery for activeEnergyBurned, with predicate nil, is registered during application(_:didFinishLaunchingWithOptions:). Background delivery is requested with frequency .immediate. The installed TestFlight app has the HealthKit and HealthKit background-delivery entitlements. With valid locally stored access, Health processing does not wait for a StoreKit subscription query. In the captured trace, observer callbacks complete promptly and healthd reports no outstanding launches afterward. Recorded test on November 7, 2026 (device-log times, UTC−07:00): Around 07:03, I manually added 40 kcal in Apple Health. At 07:03:42, Health received an added sample. healthd scheduled the next Active Energy background launch for 08:03:14, approximately one hour after our previous observer completion. At 07:05:42, I unlocked to the Home Screen. Protected Health data became available, but no corresponding observer callback reached our app. At 07:08:40, I opened our app. Its observer callback arrived immediately, and two reward notification requests were accepted without error. Earlier development installations appeared to deliver accumulated rewards upon unlocking to the Home Screen, even after the debugger had disconnected. Subscription integration occurred between those versions, but we have not established the cause of the difference. My questions: Is an approximately one-hour interval expected for activeEnergyBurned on iPhone despite requesting .immediate? Can foreground observer completions advance the next permitted background delivery time? Is there a supported way to receive pending Active Energy updates after unlocking, without opening the app or starting an HKWorkoutSession? I can provide targeted implementation details and additional relevant log excerpts if needed. Thank you.
Replies
0
Boosts
0
Views
66
Activity
3d
App crashes when connecting to Healthkit
Hello , Can anyone assist me on this issue ? i have an IOS testflight build from Replit that crashes the moment I click to connect to the Apple Health Kit. I have uploaded multiple crash logs to replit, gemini , and copilot to problem solve but so far no luck . Any insight is greatly appreciated! Mike
Replies
2
Boosts
0
Views
86
Activity
6d
Can an iPhone app receive AirPods Pro 3 heart-rate updates once per second through a supported API?
I’m building an iPhone app that aligns live heart-rate readings with a video recording. I’m looking for a supported way to receive a fresh AirPods Pro 3 BPM estimate about once per second during an active session. I tested with an iPhone 16 running iOS 27.2 and AirPods Pro 3. A minimal test app starts an HKWorkoutSession on the iPhone, collects heart rate with HKLiveWorkoutBuilder, and records the source timestamp of each distinct reading. With both .other / .indoor and .running / .outdoor, the median spacing between readings was about five seconds. Querying HealthKit afterward returned the same in-take readings. Is that cadence expected for third-party apps? Is there a documented API, workout configuration, or capability that Apple makes available to third-party developers for receiving fresh AirPods Pro 3 BPM estimates at about 1 Hz? My requirement is for a new estimate from the AirPods at that cadence. Polling more frequently or interpolating between readings would not meet it.
Replies
3
Boosts
0
Views
66
Activity
6d
Is CMSensorRecorder accelerometer recording and retrieval supported while Apple Watch is charging?
On an Apple Watch Series 4-5, our app receives no recorded accelerometer samples during charging. Repeating the query for the same interval after disconnecting the charger also returns nil. Recording without the charger produces samples. An HKWorkoutSession remains running during the unsuccessful test, and live motion collection works while charging. Is this expected behavior or a known limitation? If supported, what conditions must be met?
Replies
1
Boosts
0
Views
63
Activity
1w
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
3
Boosts
0
Views
120
Activity
1w
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
211
Activity
1w
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
423
Activity
2w
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
131
Activity
2w
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
285
Activity
2w
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
3.0k
Activity
2w
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.3k
Activity
2w
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
991
Activity
3w
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
468
Activity
3w
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
70
Activity
3w
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
125
Activity
Oct ’26