I need to be able to create and store a HeartbeatSeries for a given time-period from an Apple Watch, to then retrieve that data from HealthKit to be processed.
I have working code which allows me to begin a workout session, which is being used to determine how long a session has been running for. I also have working code for retrieving HeartbeatSeries data from HealthKit.
The issue is that no HeartbeatSeries data is being stored into HealthKit as a result of the workout session running. Whether that session is running for as little as 30 seconds or as long as 20 minutes, nothing is stored.
However, when I use the the Apple "Meditation" app (formerly known as "Breathe"), I can query HealthKit afterwards and retrieve a list of individual heartbeat timings during that 2 minute period.
Therefore, it IS possible to store a HeartbeatSeries from within an app on the Apple Watch.
What I would like to know is, how can I use the pulse sensor built-in to the Apple Watch to be able to record a HeartbeatSeries similar to how the Meditation app does it.
Health & Fitness
RSS for tagExplore the technical aspects of health and fitness features, including sensor data acquisition, health data processing, and integration with the HealthKit framework.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
My research group is using watch sensors (accelerometers, gyroscopes) to track wrist motion to detect and measure eating. https://cecas.clemson.edu/ahoover/bite-counter/
We are running an HKWorkoutSession on the watch so that the app can run for an extended period of time (up to 12 hr) and continue to sense and process motion data.
Our app is adding to the activity rings, making it look like the user is exercising the entire time our app is running. Is there a method to prevent our app from contributing to the activity ring measures?
Topic:
App & System Services
SubTopic:
Health & Fitness
Tags:
WatchKit
Health and Fitness
SensorKit
WorkoutKit
I am experiencing a critical issue with HealthKit authorization in iOS 18.5 where requestAuthorization() calls are immediately denied without showing the user permission dialog.
Problem Description:
HealthKit authorization requests immediately return .sharingDenied status
No system permission dialog is displayed to the user
Authorization status changes from .notDetermined to .sharingDenied in <0.1 seconds
This occurs for all HealthKit data types (step count, heart rate, sleep analysis, etc.)
Technical Details:
iOS Version: 18.5 (22F76)
Xcode Version: 16F6
Device: iPhone (tested on both simulator and physical device)
Bundle IDs tested: com.hereforyou.test2024, com.hereforyou.app
Entitlements: com.apple.developer.healthkit = true
Code Implementation:
let healthStore = HKHealthStore()
let stepType = HKObjectType.quantityType(forIdentifier: .stepCount)!
// Status before request: .notDetermined
try await healthStore.requestAuthorization(toShare: [], read: [stepType])
// Status after request: .sharingDenied (immediate, <0.1 seconds)
Evidence this is not a code issue:
Other HealthKit apps from App Store work correctly on the same device
Proper entitlements are configured and verified
HKHealthStore.isHealthDataAvailable() returns true
Same code worked in previous iOS versions
Multiple Bundle IDs tested with same result
Expected Behavior:
System should display HealthKit permission dialog allowing user to grant/deny access
Actual Behavior:
Authorization is immediately denied without user interaction
Steps to Reproduce:
Create new iOS app with HealthKit entitlements
Call requestAuthorization() for any HealthKit data type
Observe immediate denial without permission dialog
Is this a known issue in iOS 18.5? Are there any workarounds or timeline for a fix?
Best regards
Topic:
App & System Services
SubTopic:
Health & Fitness
HealthKit is currently not supported on macOS nor tvOS, despite being supported by visionOS. Support for macOS was last asked about[1] here in 2018.
My goal is to display interactive data visualisations over workouts collected in HealthKit on macOS. Will this be possible to do in the near future using HealthKit directly?
If not, can I somehow read the information from an iPhone and display it on the mac?
Cheers,
Rodrigo
[1] https://developer.apple.com/forums/thread/94937
New in iOS 26 and WatchOS 26 is a Sleep Score calculation for users based on Duration, Bedtime and Interruptions.
Unfortunately I can't find any APIs for developers to tap into this metric. Yes, in theory it's all created off the same Sleep Analysis data already available with HealthKit but that makes it very hard to recreate in our apps. If the numbers don't match up exactly, users will understandably complain.
Can anyone confirm that this is the case and I've not missed a Sleep Score API? I'll then file feedback.
Hopefully this doesn't go the way of Heart Rate Zones where the Apple Watch iPhone app has generated them for years and provided no way for third party apps to access these values (yes many feedbacks provided previously).
Hello,
In my application, I need to obtain precise workout segment data from HKWorkout in order to calculate per-kilometer metrics such as heart rate and pace.
My current approach is:
1.Use HKWorkout to fetch the associated HKWorkoutEvents.
2.Take the end time of one event as the start time of the next event to derive per-kilometer segment ranges.
The issue I’m facing:
•If a user sets Apple Watch to notify every 5 kilometers, then at 5 km, 10 km, 15 km, etc., I see overlapping event times.
•From the HKWorkoutEvents data alone, I cannot distinguish between events that represent “per-kilometer splits” and those that represent “5-kilometer notifications.”
•As a result, my per-kilometer heart rate and pace calculations can be inaccurate.
My question is:
Is there a recommended way to reliably differentiate per-kilometer splits from custom distance notifications and ensure accurate segment data retrieval?
For example, should I instead reconstruct segments using HKWorkoutRoute and distance samples, rather than relying on HKWorkoutEvents?
STEPS TO REPRODUCE
1.On Apple Watch, start an Outdoor Run using the Workout app.
2.In workout notifications, set distance alerts to every 5 kilometers.
3.During the run, when reaching 5 km, 10 km, 15 km, etc., the watch triggers notifications.
4.Query the corresponding HKWorkout from HealthKit and inspect its HKWorkoutEvents.
5.Notice that some event start times are duplicated, and it is unclear which events represent “per-kilometer splits” and which represent “5-kilometer notifications.”
Expected Result:
Be able to differentiate between per-kilometer splits and custom distance alerts, so that heart rate and pace per kilometer can be calculated accurately.
Actual Result:
The HKWorkoutEvents data contains duplicated event times without a way to distinguish event types, leading to inaccurate per-kilometer statistics.
Since upgrading to iOS 26 beta on my Apple Watch Ultra and iPhone 16 Pro Max, my exercise app and activity rings have sporadically not connected after charging. Several recent mornings, when I’ve put my watch on, the activity rings are grayed out and when I click on them, they will show no activity, even though I have been active. Similarly, when I attempt to select the activity app, it will open, but when I select an activity, it will not start the workout. I’ve tried starting and restarting the watch and phone. I’ve checked permissions, and both the watch and phone are running the latest iOS. The only fix seems to be unpairing and repairing the watch and phone which is an absolute pain. Any assistance on how to permanently fix this would be greatly appreciated.
Topic:
App & System Services
SubTopic:
Health & Fitness
Ever since upgrading to OS 26.1, I've noticed that HealthKit anchored object queries seem to be much slower-updating than normal. I was curious if Apple stated anything explicitly changed on this front? I use anchored object queries to update some of the workout metrics that HKLiveWorkoutBuilder doesn't report (like stepCount).
I am using this below code since WatchOS 10 to set the user steps observer and get the callback of steps whenever changes.
This is still working perfectly fine till watchOS 11 but when i updated to watchOS 26.1, I am not getting the callback of steps, like the observer is not working at all. I should get a callback inside query block whenever user take steps, but it is not working in watchOS 26.1.
func setupStepCountObserver(completion: @escaping (Double, Double) -> Void) {
let stepCountType = HKObjectType.quantityType(forIdentifier: .stepCount)!
let query = HKObserverQuery(sampleType: stepCountType, predicate: nil) { [weak self] _, completionHandler, error in
if let error = error {
print("Error setting up observer query: \(error.localizedDescription)")
return
}
// Fetch the latest step count data
self?.getLast20SecTodaysSteps(completion: completion)
// Call the completion handler to let HealthKit know you have processed the update
completionHandler()
}
// Execute the query
healthStore.execute(query)
// Enable background delivery of updates
healthStore.enableBackgroundDelivery(for: stepCountType, frequency: .immediate) { success, error in
if let error = error {
print("Error enabling background delivery steps: \(error.localizedDescription)")
} else if success {
print("Background delivery enabled for steps.")
}
}
}
Hi!
I am using the HKAnchoredObjectQuery to first get a snapshot of the initial results, and then trigger an updateHandler.
I need to handle the initial results and the updates separately, which is why I implemented two completions.
When I test the code, it works for a while. New and deleted samples trigger the updateHandler. However, after a while there appears an error:
[connection] nw_read_request_report [C2] Receive failed with error "Software caused connection abort"
Followingly, the updateHandler will stop getting triggered when I add updates in Apple health. Anyone have experience with this?
func getMostRecentSample(for sampleType: HKSampleType,
anchorKey: String,
completion: @escaping (HKQuantitySample?, Error?) -> Swift.Void,
updateHandler: @escaping (HKQuantitySample, Error?) -> Swift.Void) {
// If it is the first initialization, anchor is passed as nil
var anchor: HKQueryAnchor? = nil
// Check for previous saved anchor in userdefaults
if UserDefaults.standard.object(forKey: anchorKey) != nil {
let data = UserDefaults.standard.object(forKey: anchorKey) as! Data
do {
guard let newAnchor = try NSKeyedUnarchiver.unarchivedObject(ofClass: HKQueryAnchor.self, from: data) else {
print("Could not parse anchor to HKQueryAnchor type")
return
}
anchor = newAnchor
} catch {
print("Error retreiving anchor from UserDefaults")
}
}
let query = HKAnchoredObjectQuery(type: sampleType,
predicate: nil,
anchor: anchor,
limit: HKObjectQueryNoLimit
) { (query, samplesOrNil, _, newAnchor, errorOrNil) in
guard let samples = samplesOrNil as? [HKQuantitySample] else {
fatalError("*** An error occurred during the initial query: \(errorOrNil!.localizedDescription) ***")
}
if let anchor = newAnchor {
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: anchor as Any, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: anchorKey)
} catch {
print("Error retreiving anchor from UserDefaults")
}
}
completion(samples.last, nil)
}
// Setting up long-running query
query.updateHandler = { (query, samplesOrNil, _, newAnchor, errorOrNil) in
guard let samples = samplesOrNil as? [HKQuantitySample] else {
fatalError("*** An error occurred during an update: \(errorOrNil!.localizedDescription) ***")
}
if let anchor = newAnchor {
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: anchor as Any, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: anchorKey)
} catch {
print("Error retreiving anchor from UserDefaults")
}
}
if let sample = samples.last {
updateHandler(sample, nil)
}
}
self.healthStore.execute(query)
}
In this link, Apple states we can know when a user is in bed vs sleeping and compare their quality of sleep by it. Only, in iOS 18, Apple no longer reports inBed time samples for the Apple Watch. I get why they stopped doing this for the phone, but why the watch? Bug?
My app was using the inBed times for this very purpose and now only works for Garmin and Oura who still report inBed times.
https://developer.apple.com/documentation/healthkit/hkcategoryvaluesleepanalysis
We are seeing an issue where sending data using the asynchronous method HKWorkoutSession.sendToRemoteWorkoutSession(data: Data) will never return in some cases (no success nor failure).
This issue is happening for roughly 5% of Workouts started and will stay broken for the whole workout. The other 95% of the workouts, the connection works flawlessly. This happens on both watchOS 10 and 11, and with phones running iOS 17 or 18. The issue is quite random and not reproducible.
Our app has thousands of workouts a day that use the workout session workout data send, with constant messages being send every few seconds.
In some of those 5% cases the "sendToRemoteWorkoutSession" will throw way later, like 30+ minutes later, if the watch app is awake long enough to capture a log of a failure.
Our code uses the same flow as in the sample project:
https://developer.apple.com/documentation/healthkit/workouts_and_activity_rings/building_a_multidevice_workout_app
Here is some sample code, which is pretty simple.
Setup code:
let workoutSession = try HKWorkoutSession(healthStore: healthStore, configuration: configuration)
workoutSession.delegate = self
activeWorkoutSession?.startMirroringToCompanionDevice { success, error in
print("Mirroring started on companion device: \(success), error: \(error)")
}
workoutSession?.prepare()
then later we send data using the workout session:
do {
print("Will send data")
try await workoutSession.sendToRemoteWorkoutSession(data: data)
print("Successfully sent data") // This nor the error may be called after waiting extensive amounts of time
} catch {
print("Failed to send data, error: \(error)") // This nor the success may be called after waiting extensive amounts of time
}
So far, the only fix is to restart the phone and watch at the same time, which is not a great user experience.
Is anyone else seeing this issue? or know how to fix this issue?
Topic:
App & System Services
SubTopic:
Health & Fitness
Tags:
Watch Connectivity
Health and Fitness
watchOS
WorkoutKit
https://support.apple.com/zh-cn/104959
Our application provides car insurance services. Does Apple have any API related to car accident detection exposed to developers? We want to do something when an iPhone detects a car accident
Topic:
App & System Services
SubTopic:
Health & Fitness
We currently use the HKCategoryValueMenstrualFlow enum to determine the type of menstrual flow: light, medium, etc. a user is having. We also use this enum in determining if it's an actual period day.
The Problem
I see HKCategoryValueMenstrualFlow was recently deprecated but has not been replaced by another data type.
Are there plans to replace/update it with another data type?
When or at what point in the future will this deprecation cause a problem in my code?
I've been trying to figure out what the bare minimum is required for HKWorkoutBuilder to create a workout that adds time the appleExerciseTime. I couldn't find the documentation for this. This is my code so far.
func createWorkoutSample(
expectedActiveEnergyData: [Double],
expectedExerciseMinutesData: [Double],
calendar: Calendar,
startDate: Date
) async throws -> [HKSample] {
var testData: [HKSample] = []
let workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
let results = try await withThrowingTaskGroup(of: HKSample?.self) { group in
for (index) in 0..<expectedActiveEnergyData.count {
guard let date = calendar.date(byAdding: .day, value: index, to: startDate) else {
continue
}
group.addTask {
let builder = HKWorkoutBuilder(
healthStore: self.manager.healthStore,
configuration: workoutConfiguration,
device: .local()
)
let endDate = date.addingTimeInterval(expectedExerciseMinutesData[index] * 60)
try await builder.beginCollection(at: date)
let energyType = HKQuantityType.quantityType(
forIdentifier: .activeEnergyBurned
)!
let energyQuantity = HKQuantity(
unit: HKUnit.kilocalorie(),
doubleValue: expectedActiveEnergyData[index]
)
let energySample = HKQuantitySample(
type: energyType,
quantity: energyQuantity,
start: date,
end: endDate
)
return try await withCheckedThrowingContinuation { continuation in
builder.add([energySample]) { (success, error) in
if let error = error {
continuation.resume(throwing: error)
return
}
builder.endCollection(withEnd: endDate) { (success, error) in
if let error = error {
continuation.resume(throwing: error)
return
}
builder.finishWorkout { (workout, error) in
if let error = error {
continuation.resume(throwing: error)
return
}
continuation.resume(returning: workout)
}
}
}
}
}
}
for try await workout in group {
if let workout = workout {
testData.append(workout)
} else {
print("Skipping nil workout result.")
}
}
return testData
}
print("Total samples created: \(results.count)")
return results
}
When I query appleExerciseTime, there are no results. I've looked at the HKWorkoutBuilder documentation, and most of the information expands on adding samples related to the deprecated HKWorkout.
Is there documentation on how to read workout effort scores from a HealthKit workout? I'm interested in reading workoutEffortScore and estimatedWorkoutEffortScore. I have not been successful trying to read them using the same method that I do other workout HKQuantityTypes (heartRate, stepCount, etc). I'm using Swift and I do have authorization for those types requested and granted.
I have found documentation on setting these values (https://developer.apple.com/forums/thread/763539) but not reading them.
Thank You
Hello,
My app syncs workout data from a third-party device and records workouts with HealthKit as follows:
let builder = HKWorkoutBuilder(healthStore: healthStore, configuration: hkConf, device: hkDevice)
try await builder.beginCollection(at: startDate)
try await builder.addSamples(samples)
try await builder.endCollection(at: endDate)
let workout = try await builder.finishWorkout()
let workoutRouteBuilder = HKWorkoutRouteBuilder(healthStore: healthStore, device: hkDevice)
try await workoutRouteBuilder.insertRouteData(filteredLocations)
try await workoutRouteBuilder.finishRoute(with: workout, metadata: nil)
However, I’m encountering two issues:
The workouts appear in Apple Fitness but do not contribute to the activity rings.
The workout includes a route (visible in the raw workout data in Apple Health) but does not display on Apple Fitness.
Is there any way to fix this? I’d appreciate any suggestions you might have.
__
I am working on an Apple Watch companion app to an existing live iOS app. I am utilizing the heart rate tracking for an active 'self-care' sauna session. I say self-care in quotes because it's more self-care than a workout activity, but it is closely blurring the lines between the two.
I have come to understand that if a session truly isn't a workout, then you should not use workoutSession.startActivity. However the app needs to function entirely like a workout would. This is not a meditation application. Sauna is actually just one of many activity types supported in the app.
I have tried using extended runtime session, and there have been numerous issues with doing so. It is not nearly as robust for the user. For example, the active session is not prioritized by the watch's CPU. Now playing is no longer functional. Heart rate is far more inconsistent, and this variable is as critical as if it were in a workout.
I have tried using HKWorkoutSession, however I worry the app will be rejected by doing so. This method works most accurately to collect the right data for the user, and prioritizes system resources as expected. The app can be moved to the background as expected and continue to communicate with the iOS app.
What is the best way to move forward here. It almost feels like I am operating in a grey area with no real solution in place. Any assistance is greatly appreciated as we would like to follow all guidelines while producing a high quality experience for our users.
I can create WorkoutGoals of all kinds except .energy, but I can't find any indication of the conditions under which energy goals can be used.
No matter what I try, the response from supportsGoal is always false e.g.
CustomWorkout.supportsGoal(.energy(10, .kilojoules), activity: .running, location: .outdoor)
CustomWorkout.supportsGoal(.energy(10, .calories), activity: .cycling, location: .outdoor)
CustomWorkout.supportsGoal(.energy(10, .kilocalories), activity: .running, location: .outdoor)
For any combination I've tried, I get Not supported due to unsupportedGoal
Has anybody managed to successfully create energy goals?
In the fitness app under iOS 18, the location of all workouts is displayed on a small map.
For workouts with routes, I can already successfully read out the route and thus also determine the starting point. So that works.
For indoor workouts such as yoga or indoor rowing, the exact location is also displayed in the fitness app. I would now also like to read out this location for these indoor workouts in my app.
Does anyone know how to do this?