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've had trouble for a while now with HealthKit giving me different values if I make the request on iOS and WatchOS.
I am using the exact same method on both with the same parameters but I get vast differences in the results.
The code I am using to call HealthKit on both devices is:
let dateRange = HKQuery.predicateForSamples(withStart: Date().removeMonths(numberOfMonths: 1), end: Date().endOfDay())
let predicate: NSPredicate
predicate = NSCompoundPredicate(type: .and, subpredicates: [dateRange])
let query = HKStatisticsQuery(quantityType: HKQuantityType(.stepCount), quantitySamplePredicate: predicate, options: .cumulativeSum) { _, result, error in
if error != nil {
//print("Error fetching step count, or there is no data: \(error.localizedDescription), \(startDate) -> \(endDate)")
onComplete(0)
return
}
if let result, let sum = result.sumQuantity() {
let stepCount = sum.doubleValue(for: HKUnit.count())
DispatchQueue.main.async {
onComplete(Int(stepCount))
}
}
}
healthStore.execute(query)
}
Platform & Version:
iOS Version: 18.3.1
Development Environment: Xcode 16.2, macOS 14.6.1
Description of the Issue:
We're exploring ways to better integrate Apple Fitness+ workouts into our app. We've noticed that some third-party apps, such as Strava and HealthFit, now display Fitness+ workout details, including the title, trainer, and an image.
I’ve been investigating how this is possible, and the only relevant change I’ve found is that HKMetadataKeyAppleFitnessPlusCatalogIdentifier is now being set for Fitness+ workouts. However, I can’t find any public API or official documentation that explains how to use these identifiers to retrieve the associated workout details.
Question:
Is there an official API available to fetch metadata for Fitness+ workouts using these identifiers? Or are these third-party apps potentially accessing private APIs? If no API exists, is the only option to create a manual mapping of these identifiers—something that seems impractical given the constantly evolving Fitness+ workout catalog?
Any guidance on this would be greatly appreciated. Thanks!
Topic:
App & System Services
SubTopic:
Health & Fitness
Tags:
Health and Fitness
HealthKit
WorkoutKit
The background deliver works perfectly when the app is in the background or suspended states. However, when the app is killed (terminated state), the background task does not execute
Hello Apple Community,
What does approach use the Fitness app for swimming distance calculation per set (segment)?
I've tried 2 options but all of them have different values than in the Fitness app.
Calculation like that: pool length * number of laps = swimming distance BUT the Fitness app sometimes shows other values for distance per set (segment).
Fetch all distance values via HKQuantityTypeIdentifier.distanceSwimming (HKSampleQuery`) and than try to match distance values with set (segment) duration. Again I got other values for swimming distance per set, values are bigger than in the Fitness app.
let healthStore = HKHealthStore()
let distanceType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.distanceSwimming)!
let predicate = HKQuery.predicateForSamples(withStart: startDate as Date, end: endDate as Date?, options: .strictStartDate)
let query = HKSampleQuery(sampleType: distanceType, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: [.init(keyPath: \HKSample.startDate, ascending: true)], resultsHandler: { (query, results, error) in
if let error {
Logger.e("\(error)")
continuation.resume(returning: nil)
}
continuation.resume(returning: results)
})
healthStore.execute(query)
Is it possible to get the same swimming distance like in the Fitness app per set via HealthKit?
Topic:
App & System Services
SubTopic:
Health & Fitness
Looking for help with our Apple HealthKit integration. We've successfully pulled steps, distance, active energy, glucose and heart rate. However, the data pulled for sleep duration is incorrect. Not sure what we're doing wrong.
I'm trying to hook into the new workoutEffort score supported in iOS 18, I am collecting this information from users when they submit their workout and trying to add a sample to the HKWorkout in the same manner as I've been adding other samples like bodyweight, calories burned, etc.
I'm receiving the error:
HKWorkout: Sample of type HKQuantityTypeIdentifierWorkoutEffortScore must be related to a workout
I tried adding the samples using HKWorkoutBuilder.add([samples]) as which has been working perfectly for calories burned & bodyweight, but I am receiving the above error for workoutEffortScore
As a second approach, I tried adding the sample after I called finishWorkout on the HKWorkoutBuilder and received back the HKWorkout object using HKHealthStore.add([samples], to: HKWorkout) and am still receiving the same error!
I don't know otherwise how to relate a sample to a workout, I thought those were the APIs to do so? I'm using Xcode 16.0 RC (16A242) and testing on an iOS 16 Pro simulator
I am working on a Smart Alarm app for Watch OS.
When testing on an Series 10 watch, I am successfully able to read heart rate data in the ExtendedRuntimeSession. However, although the calls succeed, the sleep analysis data is all 0.
The app successfully gets authorization for:
[HKQuantityType(.heartRate), HKObjectType.categoryType(forIdentifier: .sleepAnalysis)!]
I have read that sleep data is not available for less than an hour time period. The Smart Alarm extended session has a 30 minute limit.
Does that mean it is not possible to read sleep analysis data in a Smart Alarm extended session?
Thank you!
I have an App in objective-c that is using Health data (walk/run, cycling) to give advice to users . I do not want/need to write any data in the Healtkit.
If i do (with the 3 values in the plist / .info :
self.healthStore requestAuthorizationToShareTypes:nil readTypes:readDataTypes
My request crashes.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Must request authorization for at least one data type'
*** First throw call stack:
(
0 CoreFoundation 0x00000001804b910c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x0000000180092da8 objc_exception_throw + 72
2 CoreFoundation 0x00000001804b901c -[NSException initWithCoder:] + 0
3 HealthKit 0x000000019da034d4 -[HKHealthStore _validateAuthorizationRequestWithShareTypes:readTypes:] + 92
4 HealthKit 0x000000019da03670 -[HKHealthStore requestAuthorizationToShareTypes:readTypes:shouldPrompt:completion:] + 292
BUT in swift :
healthStore.requestAuthorization(toShare: nil, read: readTypes)
is working, présents only my 2 datas to read... in the same IOS , same phone without crashing. What is the difference ?
Nil object in objective-c and Nil object in swift are not the same ? how do i make readonly requests in objective C ?
Hi everyone!
I'm trying to get the total sleep time for a given day, but users report that there's a difference between what my app reports and what the Apple Health app reports. In particular, we're off by 2 minutes less on average.
What we're doing is:
Get all the samples that are either core, deep, rem or unspecified
Cut-off time at 3 PM previous day
Merge overlapping intervals
Add all the remaining intervals
For debugging purposes I'm storing and sending all the raw samples to a server, and I have run tests and I don't find anything wrong. It looks like the number we come up with is correct according to our own rules. I wonder, how is Apple adding up all the samples to arrive at a number that's slightly off to our number.
Any insight would be appreciated. Thanks.
When I set the distanceFilter = 5 (5 meters) in the GPS CLLocationManager
I can't display the workout routes in the Apple Fitness app after writing the recorded GPS data to HealthKit via HKWorkoutRouteBuilder.
The smaller distanceFilter, Fitness will displays the route.
Should I consider setting up a small distanceFilter when developing a workout app on watchOS?
Hi, i'm trying to get the number of step counts a person has taken. I decided to pull the data from health kit and the number of steps are incorrect. Come to find out apple health recommends an app called pedometer++ for the number of steps counted and after testing I realized that they are getting the correct number of steps a person is taking. How can I pull the correct number of steps a person has taken? I want to be able to merge the data from watch and phone to make sure we are getting the correct number of steps but not double counting the steps either.
any guidance on this would be appreciated!
Here's the code snippet that i'm using right now:
permissions: {
read: [AppleHealthKit.Constants.Permissions.StepCount],
write: [],
},
};
AppleHealthKit.initHealthKit(permissions, error => {
if (error) {
console.log('Error initializing HealthKit: ', error);
return;
} else {
dispatch(setAllowHealthKit(true));
getHealthKitData();
console.log('HealthKit initialized successfully');
}
});
const getHealthKitData = async () => {
try {
const today = new Date();
const options = {
startDate: new Date(today.setHours(0, 0, 0, 0)).toISOString(),
endDate: new Date().toISOString(),
};
const steps = await new Promise((resolve, reject) => {
AppleHealthKit.getStepCount(options, (error, results) => {
if (error) reject(error);
resolve(results?.value);
});
});
setStepsCount(steps);
} catch (error) {
console.error('Error fetching HealthKit data:', error);
}
};