Post

Replies

Boosts

Views

Activity

Reply to How to monitor heart rate in background without affecting Activity Rings?
Hi @Ziqiao Chen and everyone, Thank you for the follow-up. You were right to push for more precise testing — it led me to discover an issue with my original test setup and reach a much clearer understanding of the problem. == Correction: Original Test Setup == My initial frontmost test had a build configuration error: the test build still had an active HKWorkoutSession running in the background. This means the results I would have reported (~10 minutes before termination) did not reflect pure frontmost app state behavior. I've since corrected this and re-tested with precise instrumentation. == Hardware & Software == Apple Watch Series 8 (45mm) — not Series 4 watchOS 11.6.1 (latest stable) Build: Debug, standalone watch app Xcode debugger disconnected before all tests (to avoid priority elevation) == Methodology == I added a 30-second heartbeat timer that logs: Sequential counter and elapsed seconds Current heart rate value and time since last HR sample (hr_age_sec) App lifecycle transitions (ScenePhase changes) I also ran a comparison test with HKWorkoutSession enabled (Release build) as a control group. Settings: Return to Clock → per-app Custom → After 1 Hour == Finding 1: App Process Alive, But Timers Stop == With frontmost mode (no HKWorkoutSession), the app process remained alive for the full 65 minutes (matching the 1-hour Return to Clock setting). ScenePhase callbacks (active/inactive oscillation) continued throughout the entire 65 minutes at varying intervals (ranging from a few seconds to several hundred seconds) — the system kept delivering lifecycle events to the app. However, Timer.scheduledTimer stopped firing within minutes: Heartbeat timer (30s interval): stopped after 1.5 to 6.5 minutes across different sessions — despite ScenePhase callbacks continuing for the remainder of the hour ScenePhase: active/inactive oscillation continued from T+13s through T+3903s (65 min), at varying intervals (seconds to hundreds of seconds) This suggests the app process receives system-delivered events, but the run loop stops processing scheduled timers after ~7 minutes In other words: the app can "hear" the system, but cannot "do work" on its own schedule. == Finding 2: No High-Frequency Heart Rate Without HKWorkoutSession == This is the critical finding. Without HKWorkoutSession, the heart rate sensor does not perform high-frequency sampling for the app. In our testing, HKAnchoredObjectQuery received virtually no data in frontmost mode. After a full watch reboot, I started 5 separate frontmost sessions. None of them received any heart rate data from HKAnchoredObjectQuery. A longer session (65 minutes) also received no new heart rate samples throughout its entire duration. == Finding 3: HKWorkoutSession Comparison (Control Group) == For comparison, I ran the same app with HKWorkoutSession enabled (.mindAndBody activity type): HR check: passed immediately Heart rate: updating in real-time throughout the session App survival: 10+ minutes with continuous execution (no suspension) This confirms that HKWorkoutSession is the mechanism that triggers high-frequency heart rate sampling, not just background execution. == Summary == Aspect Frontmost Only HKWorkoutSession App process alive 65 min (full hour) Indefinite System callbacks Throughout (65 min) Continuous Scheduled timers Stopped within minutes Continuous Heart rate sampling Virtually none High-freq (1-5s) Activity Rings Not affected Affected Viable for sleep No Yes detection? Frontmost app state solves the "app staying alive" part of the problem, but it cannot solve the "real-time heart rate sampling" part. The heart rate sensor simply does not provide high-frequency data without an active HKWorkoutSession. For my use case (detecting sleep onset via real-time heart rate trends during 15-60 minute nap sessions), HKWorkoutSession remains the only viable mechanism. Is there any other API or session type that triggers high-frequency heart rate sampling besides HKWorkoutSession? I've filed FB22115959 for this. If there's a better channel to discuss the specifics of my use case, I'm happy to follow up there.
Mar ’26
Reply to How to monitor heart rate in background without affecting Activity Rings?
Hi @Ziqiao Chen and everyone, Thank you @simonfromhelix for reviving this thread. @Ziqiao Chen — I tested the frontmost app state approach as you suggested. Sharing the full results here in case they're useful. == Test Setup == Disabled HKWorkoutSession entirely (no workout session started) Used only HKAnchoredObjectQuery for heart rate sampling Set Return to Clock → PowerNap (per-app Custom) → "After 1 Hour" Ran the app, then lowered my wrist to simulate a real nap scenario == Results == With Xcode debugger attached: HR sampling worked great (~5 second intervals), continuous and stable This initially gave me hope! Without Xcode debugger (real-world scenario): The app was terminated by the system within ~10 minutes, even with Return to Clock set to 1 hour for this specific app After lowering my wrist, the screen turned off and the app was suspended/killed shortly after Zero heart rate samples were collected The Xcode debugger appears to elevate the app's priority, masking the real behavior Digital Crown: Pressing the Crown navigates away and HR sampling stops immediately For a sleep app, users will inevitably press this accidentally while napping Activity Rings (positive!): Confirmed: no workout record created, Activity Rings unaffected This is exactly what we'd want — if only the app could stay alive I hope the test results above are also helpful for anyone with similar requirements. == Where this leaves me == @Ziqiao Chen — given that frontmost doesn't survive real sleep conditions, and there's no way to avoid Activity Rings with HKWorkoutSession (as you confirmed), I'd love your guidance: What would be the recommended technical approach for an app that needs real-time heart rate sampling (every few seconds) during user-initiated sessions of 15-60 minutes? I've filed FB22115959 requesting an API for this use case, and I'm happy to provide additional technical details through whichever channel you'd recommend. Thank you again for your time. This thread has been incredibly valuable, and I hope the test data above helps other developers in similar situations.
Mar ’26
Reply to How to monitor heart rate in background without affecting Activity Rings?
Hi @Ziqiao Chen and everyone, Thank you for the follow-up. You were right to push for more precise testing — it led me to discover an issue with my original test setup and reach a much clearer understanding of the problem. == Correction: Original Test Setup == My initial frontmost test had a build configuration error: the test build still had an active HKWorkoutSession running in the background. This means the results I would have reported (~10 minutes before termination) did not reflect pure frontmost app state behavior. I've since corrected this and re-tested with precise instrumentation. == Hardware & Software == Apple Watch Series 8 (45mm) — not Series 4 watchOS 11.6.1 (latest stable) Build: Debug, standalone watch app Xcode debugger disconnected before all tests (to avoid priority elevation) == Methodology == I added a 30-second heartbeat timer that logs: Sequential counter and elapsed seconds Current heart rate value and time since last HR sample (hr_age_sec) App lifecycle transitions (ScenePhase changes) I also ran a comparison test with HKWorkoutSession enabled (Release build) as a control group. Settings: Return to Clock → per-app Custom → After 1 Hour == Finding 1: App Process Alive, But Timers Stop == With frontmost mode (no HKWorkoutSession), the app process remained alive for the full 65 minutes (matching the 1-hour Return to Clock setting). ScenePhase callbacks (active/inactive oscillation) continued throughout the entire 65 minutes at varying intervals (ranging from a few seconds to several hundred seconds) — the system kept delivering lifecycle events to the app. However, Timer.scheduledTimer stopped firing within minutes: Heartbeat timer (30s interval): stopped after 1.5 to 6.5 minutes across different sessions — despite ScenePhase callbacks continuing for the remainder of the hour ScenePhase: active/inactive oscillation continued from T+13s through T+3903s (65 min), at varying intervals (seconds to hundreds of seconds) This suggests the app process receives system-delivered events, but the run loop stops processing scheduled timers after ~7 minutes In other words: the app can "hear" the system, but cannot "do work" on its own schedule. == Finding 2: No High-Frequency Heart Rate Without HKWorkoutSession == This is the critical finding. Without HKWorkoutSession, the heart rate sensor does not perform high-frequency sampling for the app. In our testing, HKAnchoredObjectQuery received virtually no data in frontmost mode. After a full watch reboot, I started 5 separate frontmost sessions. None of them received any heart rate data from HKAnchoredObjectQuery. A longer session (65 minutes) also received no new heart rate samples throughout its entire duration. == Finding 3: HKWorkoutSession Comparison (Control Group) == For comparison, I ran the same app with HKWorkoutSession enabled (.mindAndBody activity type): HR check: passed immediately Heart rate: updating in real-time throughout the session App survival: 10+ minutes with continuous execution (no suspension) This confirms that HKWorkoutSession is the mechanism that triggers high-frequency heart rate sampling, not just background execution. == Summary == Aspect Frontmost Only HKWorkoutSession App process alive 65 min (full hour) Indefinite System callbacks Throughout (65 min) Continuous Scheduled timers Stopped within minutes Continuous Heart rate sampling Virtually none High-freq (1-5s) Activity Rings Not affected Affected Viable for sleep No Yes detection? Frontmost app state solves the "app staying alive" part of the problem, but it cannot solve the "real-time heart rate sampling" part. The heart rate sensor simply does not provide high-frequency data without an active HKWorkoutSession. For my use case (detecting sleep onset via real-time heart rate trends during 15-60 minute nap sessions), HKWorkoutSession remains the only viable mechanism. Is there any other API or session type that triggers high-frequency heart rate sampling besides HKWorkoutSession? I've filed FB22115959 for this. If there's a better channel to discuss the specifics of my use case, I'm happy to follow up there.
Replies
Boosts
Views
Activity
Mar ’26
Reply to How to monitor heart rate in background without affecting Activity Rings?
Hi @Ziqiao Chen and everyone, Thank you @simonfromhelix for reviving this thread. @Ziqiao Chen — I tested the frontmost app state approach as you suggested. Sharing the full results here in case they're useful. == Test Setup == Disabled HKWorkoutSession entirely (no workout session started) Used only HKAnchoredObjectQuery for heart rate sampling Set Return to Clock → PowerNap (per-app Custom) → "After 1 Hour" Ran the app, then lowered my wrist to simulate a real nap scenario == Results == With Xcode debugger attached: HR sampling worked great (~5 second intervals), continuous and stable This initially gave me hope! Without Xcode debugger (real-world scenario): The app was terminated by the system within ~10 minutes, even with Return to Clock set to 1 hour for this specific app After lowering my wrist, the screen turned off and the app was suspended/killed shortly after Zero heart rate samples were collected The Xcode debugger appears to elevate the app's priority, masking the real behavior Digital Crown: Pressing the Crown navigates away and HR sampling stops immediately For a sleep app, users will inevitably press this accidentally while napping Activity Rings (positive!): Confirmed: no workout record created, Activity Rings unaffected This is exactly what we'd want — if only the app could stay alive I hope the test results above are also helpful for anyone with similar requirements. == Where this leaves me == @Ziqiao Chen — given that frontmost doesn't survive real sleep conditions, and there's no way to avoid Activity Rings with HKWorkoutSession (as you confirmed), I'd love your guidance: What would be the recommended technical approach for an app that needs real-time heart rate sampling (every few seconds) during user-initiated sessions of 15-60 minutes? I've filed FB22115959 requesting an API for this use case, and I'm happy to provide additional technical details through whichever channel you'd recommend. Thank you again for your time. This thread has been incredibly valuable, and I hope the test data above helps other developers in similar situations.
Replies
Boosts
Views
Activity
Mar ’26