Can’t get the live data from ppg sensor (se os 26.x) for 0 latency parsing of haptics per each pulse (heart beat). any help would be cool.
b
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
Hi everyone,
we’re developing an app that lets users export selected bike rides to the HealthKit ecosystem. We created our app icon using the Apple Icon Composer and referenced the composer file in Xcode. Everything works fine, except that the logo doesn’t appear correctly in the Fitness app.
Has anyone experienced this issue or knows how to fix it?
Topic:
App & System Services
SubTopic:
Health & Fitness
Tags:
Health and Fitness
HealthKit
Icon Composer
The second time i start a workout session, the beginCollection instance method on HKLiveWorkoutBuilder freezes.
To recreate run the Apple Sample Project Building a multidevice workout app. It looks like a bug with the HealthKit SDK and not the code but i could be wrong. The only workaround i found was erasing the simulator and reinstalling the app.
Hi!
I have over 800 days strike in closing my move circle. However oerfect month badge is not popping up for November, we have now mid of Dec and still no update.
I updated iOS to 26, did multiple resets and hard resets and still no badge. I checked many forums and post but any of given tips is working in my case.
i know it sounds funny, but it’s frustrating that I’m not getting this little gold medal to keep me motivated 😅
does anyone know how to deal with it? Is it common issue?
I'm developing a watchOS nap app that detects when the user falls asleep by monitoring heart rate changes.
== Technical Implementation ==
HKWorkoutSession (.mindAndBody) for background execution
HKAnchoredObjectQuery for real-time heart rate data
CoreMotion for movement detection
== Battery Considerations ==
Heart rate monitoring ONLY active when user explicitly starts a session
Monitoring continues until user is awakened OR 60-minute limit is reached
If no sleep detected within 60 minutes, session auto-ends
(user may have abandoned or forgotten to stop)
App displays clear UI indicating monitoring is active
Typical session: 15-30 minutes, keeping battery usage minimal
== The Problem ==
HKWorkoutSession affects Activity Rings during the session. Users receive
"Exercise goal reached" notifications while resting — confusing.
== What I've Tried ==
Not using HKLiveWorkoutBuilder → Activity Rings still affected
Using builder but not calling finishWorkout()
(per https://developer.apple.com/forums/thread/780220)
→ Activity Rings still affected
WKExtendedRuntimeSession (self-care type)
(per https://developer.apple.com/forums/thread/721077)
→ Only ~10 min runtime, need up to 60 min
HKObserverQuery + enableBackgroundDelivery
(per https://developer.apple.com/forums/thread/779101)
→ ~4 updates/hour, too slow for real-time detection
Audio background session for continuous processing
(suggested in https://developer.apple.com/forums/thread/130287)
→ Concerned about App Store rejection for non-audio app;
if official approves this technical route, I can implement in this direction
Some online resources mention "Health Monitoring Entitlement" from WWDC 2019
Session 251, but I could not find any official documentation for this entitlement.
Apple Developer Support also confirmed they cannot locate it?
== My Question ==
Is there any supported way to:
Monitor heart rate in background for up to 60 minutes
WITHOUT affecting Activity Rings or creating workout records?
If this requires a special entitlement or API access, please advise on
the application process. Or allow me to submit a code-level support request.
Any guidance would be greatly appreciated. Thank you!
Topic:
App & System Services
SubTopic:
Health & Fitness
Tags:
Entitlements
Health and Fitness
HealthKit
Hello everyone,
I’m experiencing a visual issue when dismissing a sheet on iOS 26.
I’m using the same implementation shown in the official Apple documentation. While testing, I noticed that some apps do not exhibit this behavior. However, when running this code on iOS 26, the issue consistently occurs.
Issue description:
The sheet dismisses abruptly
A white screen briefly appears for a few milliseconds and then disappears
This results in a noticeable visual glitch and a poor user experience
I tested the exact same code on iOS 18, where the sheet dismisses smoothly and behaves as expected, without any visual artifacts.
Has anyone else encountered this issue on iOS 26?
Is this a known bug, or is there a recommended workaround?
Any insights would be greatly appreciated.
Thank you.
I'm currently collecting real-time heart rate data using HKWorkoutSession. I want to track when the Apple Watch is physically removed from the user's wrist during an active workout.
However, I've noticed that workoutBuilder(_:didCollectDataOf:) continues to be called even after the watch is removed from the wrist.
Is there a way to detect when the Apple Watch is removed from the wrist during an active HKWorkoutSession? Or is this tracking not possible through the HealthKit framework?
Any guidance or alternative approaches would be appreciated.
I don't understand why elevation data is not stored in the sample using a standard length unit. Why is it stored in HKQuantityTypeIdentifier.flightsClimbed (which is 10 feet)?
Surely it is not a memory usage issue.
Treadmill GATT provides elevation in meters.
Using HKMetadataKeyElevationAscended for the total elevation gain throws away a lot of data.
Why is there no support for weighted vest or backpack? Changing body weight is not the same and provides incorrect energy. Users want to compare workouts with different weights. I don't see any metadata key for carried weight.
Topic:
App & System Services
SubTopic:
Health & Fitness
How do I add my hospital to the list of hospitals available on the Health Records on iPhone application?
I have FB12696743 open since July 21, 2023 and this happened again today.
I get home at approx 10 mins after the hour, walk appox 50 ft across my yard, up 5 steps into my house, let the dog out and pace on my deck watching the dog, go back in the house walk around the kitchen while preparing dinner. A total of about 200 ft. I sit down about 35 past the hour and start to eat and at 10 mins to the next our and I get the reminder to stand.
On the other side I wake up at 5 mins to hour. Walk 8 steps to the bathroom and successfully achieve the stand for that hour.
WHY!?!?!? 😁🤣
For a given date, there are discrepancies between the step counts obtained from HealthKit and those displayed in the Health app. Is it possible for such discrepancies to occur even if step counts are not manually entered and multiple devices are not being used?
I keep seeing a red action item to complete a task in settings. IOS beta keeps indicating that I need to enable sensor & usage data. Everything is enabled. I literally enabled everything to get it to go away, but it is still there. Suggestions?
I implemented this to receive updates for specific data types and keep the latest daily information up to date. However, for some reason, it only works for a while before stopping completely.
Background Delivery
internal func backgroundDeliveryForReadTypes(enable: Bool, types: Set<HKQuantityType>) async {
do {
if enable {
try await statusForAuthorizationRequest(toWrite: [], toRead: types)
for type in types {
try await healthStore.enableBackgroundDelivery(for: type, frequency: .daily)
}
} else {
for type in types {
try await healthStore.disableBackgroundDelivery(for: type)
}
}
} catch {
debugPrint("Error enabling background delivery: \(error.localizedDescription)")
}
}
HKQueryAnchor
internal var walkingActivityQueryAnchor: HKQueryAnchor? {
get {
if let anchorData = UserDefaults.standard.data(forKey: "walkingActivityAnchor") {
return try? NSKeyedUnarchiver.unarchivedObject(ofClass: HKQueryAnchor.self, from: anchorData)
}
return nil
}
set {
if let newAnchor = newValue {
let anchorData = try? NSKeyedArchiver.archivedData(withRootObject: newAnchor, requiringSecureCoding: true)
UserDefaults.standard.set(anchorData, forKey: "walkingActivityAnchor")
} else {
UserDefaults.standard.removeObject(forKey: "walkingActivityAnchor")
}
}
}
HKAnchoredObjectQuery
internal func observeWalkingActivityInBackground(
_ start: Bool,
toRead: Set<HKQuantityType>,
completion: @escaping @Sendable (Result<WalkingActivityData?, Error>) -> Void
) {
if start {
guard (walkingActivityQuery == nil) else {
return
}
let predicate = getPredicate(date: Date())
let queryDescriptors = toRead.map {
HKQueryDescriptor(sampleType: $0, predicate: predicate)
}
let handleSamples: @Sendable (HKAnchoredObjectQuery, [HKSample]?, [HKDeletedObject]?, HKQueryAnchor?, Error?) -> Void = { [weak self] _, samples, _, newAnchor, error in
guard let self = self else { return }
if let error = error {
completion(.failure(error))
return
}
guard let samples = samples, !samples.isEmpty else {
completion(.success(nil))
return
}
Task {
self.walkingActivityQueryAnchor = newAnchor
let activity = await self.getWalkingActivity(date: Date())
completion(.success(activity))
}
}
let query = HKAnchoredObjectQuery(
queryDescriptors: queryDescriptors,
anchor: walkingActivityQueryAnchor,
limit: HKObjectQueryNoLimit,
resultsHandler: handleSamples
)
query.updateHandler = handleSamples
healthStore.execute(query)
walkingActivityQuery = query
} else {
if let query = walkingActivityQuery {
healthStore.stop(query)
walkingActivityQuery = nil
}
}
}
WalkingActivityData
private func getWalkingActivity(date: Date) async -> WalkingActivityData {
async let averageHeartRate = try await self.getAverageHeartRate(date: date)
async let steps = try self.getStepCount(date: date)
async let durationMinutes = try self.getTotalDurationInMinutes(date: date)
async let distanceMeters = try self.getDistanceWalkingRunning(date: date, unit: .meter())
async let activeCalories = try self.getActiveEnergyBurned(date: date)
return await WalkingActivityData(
date: date,
steps: try? steps,
activeCalories: try? activeCalories,
distanceMeters: try? distanceMeters,
durationMinutes: try? durationMinutes,
averageHeartRate: try? averageHeartRate
)
}
Example of getAverageHeartRate
func getAverageHeartRate(date: Date) async throws -> Double? {
let type = HKQuantityType(.heartRate)
_ = try checkAuthorizationStatus(for: type)
guard let heartRate = try await getDescriptor(
date: date,
type: type,
options: .discreteAverage
).result(for: healthStore)
.statistics(for: date)?
.averageQuantity()?.doubleValue(for: HKUnit.count().unitDivided(by: HKUnit.minute()))
else {
return nil
}
return Double(String(format: "%.2f", heartRate)) ?? 0.0
}
Descriptor & predicate
internal func getPredicate(startDate: Date, endDate: Date) -> NSCompoundPredicate {
let predicateForSamples = HKQuery.predicateForSamples(withStart: startDate, end: endDate)
let excludeManual = NSPredicate(format: "metadata.%K != YES", HKMetadataKeyWasUserEntered)
return NSCompoundPredicate(andPredicateWithSubpredicates: [predicateForSamples, excludeManual])
}
internal func getDescriptor(startDate: Date, endDate: Date, type: HKQuantityType, options: HKStatisticsOptions) -> HKStatisticsCollectionQueryDescriptor {
let calendar = Calendar(identifier: .gregorian)
let anchorDate = calendar.date(bySetting: .hour, value: 0, of: startDate)!
var interval = DateComponents()
interval.day = 1
return HKStatisticsCollectionQueryDescriptor(
predicate: HKSamplePredicate.quantitySample(type: type, predicate: getPredicate(startDate: startDate, endDate: endDate)),
options: options,
anchorDate: anchorDate,
intervalComponents: interval
)
}
Implementation
public func observeWalkingActivityInBackground(_ start: Bool, toRead: Set<HKQuantityType>, memberID: String) {
observeWalkingActivityInBackground(start, toRead: toRead) { [weak self] result in
guard let self = self else { return }
}
}
This is an ongoing issue that I haven't been able to solve:
I am querying different types of HealthKit data over the past year. While this works fine for HRV, it hangs for some users when I'm trying to get heart rate data.
Here's the relevant query
func initialRead(from startDate: Date) async throws -> [HKSample] {
let endDate = anchorStart
let interval: TimeInterval = .days(7)
var currentStartDate = startDate
var currentEndDate = Date(timeInterval: interval, since: currentStartDate)
var samples: [HKSample] = []
while currentStartDate <= endDate {
let datePredicate = SampleType.datePredicate(start: currentStartDate, end: currentEndDate)
let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [datePredicate,HKQuery.predicateForObjects(withMetadataKey: HKMetadataKeyHeartRateMotionContext, allowedValues: [HKHeartRateMotionContext.sedentary])])
do {
let result = try await withCheckedThrowingContinuation { continuation in
let completionQuery = HKSampleQuery(sampleType: HKQuantityType.heartRate, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: [.init(key: HKSampleSortIdentifierStartDate, ascending: true)]) { query, samples, error in
if let samples {
continuation.resume(returning: samples)
} else {
if let error {
continuation.resume(throwing: error)
} else {
continuation.resume(returning: [])
}
}
}
healthStore.execute(completionQuery)
}
samples = samples.merge(from: result)
} catch {
Logger.general.error("Reading failed for dates \(currentStartDate) to \(currentEndDate): \(error)")
}
currentStartDate = currentEndDate
currentEndDate = Date(timeInterval: interval, since: currentStartDate)
}
return samples
}
extension HKSampleType {
static func datePredicate( start:Date?, end:Date?) -> NSPredicate {
HKQuery.predicateForSamples(withStart: start, end:end, options: .strictStartDate)
}
}
For reference, I expect about 1000 sedentary samples per week. Basically what happens for these users is when they start reading the HR data, the app hangs. They start each read manually via a special TestFlight build with buttons for starting the different data type readings.
Any advice on how to proceed with this bug would be great since it only affects some users.
I am able to create test builds for this audience to test different options. One theory is the motion context predicate is screwing something up. If any apple dev can enlighten me how to narrow down the issue, that would be great.
We are developing a mobile app focused on lone worker protection, which does not include any fitness tracking features.
We require the use of HKWorkoutSession solely to enable background execution of critical safety-related code.
Could you please confirm whether this use of HKWorkoutSession is permitted under App Store Review guidelines, given that our app does not offer fitness or workout-related functionality?
I am trying to track a user's real-time sleep state using heart rate data, but I have encountered several issues:
When using HKSampleQuery on the phone to fetch heart rate data, I can only retrieve data recorded before the app comes to the foreground or before it is terminated and restarted (see related issue: https://developer.apple.com/forums/thread/774953).
I attempted to get data on the Apple Watch and send updates to the phone via Watch Connectivity. However, if I use WKExtendedRuntimeSession, although I can obtain data on the watch, once the watch screen goes off, it can no longer transmit data via Watch Connectivity to the phone (since I cannot guarantee the app will remain in the foreground when lying in bed).
On the other hand, using HKWorkoutSession results in interference with the activity rings and causes the heart rate sensor to run too frequently, which I worry may affect the battery life of the watch.
Is there an elegant solution for tracking a user's heart rate data for sleep monitoring?
I am currently developing an app that measures HRV to estimate stress levels.
To align the values more closely with those from Galaxy devices, I decided not to use the heartRateVariabilitySDNN value provided by HealthKit.
Instead, I extracted individual interbeat intervals (IBI) using the HKHeartBeatSeries data.
Can I obtain accurate IBI data using this method?
If not, I would like to know how I can retrieve more precise data.
Any insights or suggestions would be greatly appreciated.
Here is a sample code I tried.
@Observable
class HealthKitManager: ObservableObject {
let healthStore = HKHealthStore()
var ibiValues: [Double] = []
var isAuthorized = false
func requestAuthorization() {
let types = Set([
HKSeriesType.heartbeat(),
HKQuantityType.quantityType(forIdentifier: .heartRateVariabilitySDNN)!,
])
healthStore.requestAuthorization(toShare: nil, read: types) { success, error in
DispatchQueue.main.async {
self.isAuthorized = success
if success {
self.fetchIBIData()
}
}
}
}
func fetchIBIData() {
var timePoints: [TimeInterval] = []
var absoluteStartTime: Date?
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(identifier: "Asia/Seoul")
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS"
var calendar = Calendar.current
calendar.timeZone = TimeZone(identifier: "Asia/Seoul") ?? .current
var components = DateComponents()
components.year = 2025
components.month = 4
components.day = 3
components.hour = 15
components.minute = 52
components.second = 0
let startTime = calendar.date(from: components)!
components.hour = 16
components.minute = 0
let endTime = calendar.date(from: components)!
let predicate = HKQuery.predicateForSamples(withStart: startTime,
end: endTime,
options: .strictStartDate)
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)
let query = HKSampleQuery(sampleType: HKSeriesType.heartbeat(),
predicate: predicate,
limit: HKObjectQueryNoLimit,
sortDescriptors: [sortDescriptor]) { (_, samples, _) in
if let sample = samples?.first as? HKHeartbeatSeriesSample {
absoluteStartTime = sample.startDate
let startDateKST = dateFormatter.string(from: sample.startDate)
let endDateKST = dateFormatter.string(from: sample.endDate)
print("series start(KST):\(startDateKST)\tend(KST):\(endDateKST)")
let seriesQuery = HKHeartbeatSeriesQuery(heartbeatSeries: sample) {
query, timeSinceSeriesStart, precededByGap, done, error in
if !precededByGap {
timePoints.append(timeSinceSeriesStart)
}
if done {
for i in 1..<timePoints.count {
let ibi = (timePoints[i] - timePoints[i-1]) * 1000 // Convert to milliseconds
// Calculate absolute time for current beat
if let startTime = absoluteStartTime {
let beatTime = startTime.addingTimeInterval(timePoints[i])
let beatTimeString = dateFormatter.string(from: beatTime)
print("IBI: \(String(format: "%.2f", ibi)) ms at \(beatTimeString)")
}
self.ibiValues.append(ibi)
}
}
}
self.healthStore.execute(seriesQuery)
} else {
print("No samples found for the specified time range")
}
}
self.healthStore.execute(query)
}
}
Hi,
I’m currently working on an app that utilizes sleep data from HealthKit to provide users with meaningful insights about their sleep.
To ensure a smooth user experience, I’d like to understand when sleep data collected by the Apple Watch is saved to the HealthKit store and when it gets synced to the iPhone.
Ideally, I want to fetch sleep data right after the user wakes up and opens our app. However, to do this reliably, I need to know the timing of how and when this data becomes available in the iPhone’s HealthKit store.
I’ve looked through the official documentation and relevant WWDC sessions but couldn’t find clear information on this topic.
If anyone has insights or experience with how and when the Apple Watch syncs HealthKit data—especially sleep records—to the iPhone, I’d greatly appreciate your input.
Thanks!
Hello,
I’m developing an iOS app that works with sleep data from Apple Watch via HealthKit. I would like to clarify the following:
How can an iPhone app detect when a sleep session ends on the Apple Watch?
When is sleep data typically written to the HealthKit store on iPhone after sleep ends? Is it immediately after wake-up, or does it depend on certain conditions (e.g., watch charging, connectivity)?
Understanding the timing and mechanism of sleep data synchronization is crucial for our app to process accurate and timely health information.
Thank you for your assistance.
I want to know , how many days will the data of health stays in apple watch . For example, I have not synced the watch with iPhone for two weeks . Then When I synced it , I am only able to see the last week data on iPhone of the watch . Is it true ?