The HealthKit permission sheet is showing up every time the app opens for a few users of my app. It doesn't matter what action they take in the sheet. I have had them try toggling the permissions from the HealthKit system settings but that did not happen to fix the problem.
Has anyone experienced this problem or know a fix? Its affecting a few users of my app. I haven't been able to find what in my code could be doing this, I suspect its a bug on HealthKit's side for specific users. I can't find anyone reporting this problem elsewhere so I have to assume its my fault, but the docs clearly state that the permission sheet will only be presented once.
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.
Post
Replies
Boosts
Views
Activity
When I record a workout with iPhone, the workout is displayed in the exercise ring. But not with iPad. A workout from iPad is recorded, it is in "Health" app history, but the exercise ring does not display it. Why is the workout not displayed on the exercise ring on iPad?
I'm looking to access the HKMetadataKeyWeatherCondition that indicates the weather during a workout (sunny, cloudy, rain, etc.). I have accessed the workout metadata where I can see temperature and humidity but the weather enum eludes me. Any help would be appreciated.
I'm looking at a swimming workout sample and in the metadata I see:
Optional(["HKIndoorWorkout": 0, "HKSwimmingLocationType": 2, "HKAverageMETs": 10.7366 kcal/hr·kg, "HKTimeZone": America/New_York])
There is no mention of the HKMetadataKeySwimmingStrokeStyle yet when I look at the workout in the Apple Fitness app, there is stroke style data.
How can I access the stroke enum?
Hello, We are currently developing a healthcare app using React Native and have successfully implemented the feature to fetch data such as step count, weight, blood pressure, and heart rate from HealthKit.
While we have no issues with the data retrieval itself, we have encountered a problem regarding the blood pressure data. In HealthKit's Heart → Blood Pressure → Data Sources & Access section, the "APPS AND SERVICES ALLOWED TO READ DATA" shows as "NONE," and there's no option within HealthKit to toggle the connection ON or OFF. Instead, the control for ON/OFF is available in the iPhone's SETTINGS → Health → Data Sources & Access, specifically for "Diastolic Blood Pressure" and "Systolic Blood Pressure".
Please note that the ability to toggle ON/OFF within HealthKit is available for step count, weight, and heart rate.
Could this issue with blood pressure data be due to the requirement of two permissions (for diastolic and systolic readings), and that's why it's not displayed correctly in HealthKit? What are the possible solutions for controlling the blood pressure data ON/OFF toggle within HealthKit?
Could you please provide clarification on whether WatchOS currently supports the real-time or on-demand measurement of skin temperature and ambient temperature? If so, Could you also guide us on the relevant APIs or resources available for incorporating these features into out applications?
Hello, our app has been rejected in the review of version update, we need to provide relevant medical certificates. And our classification is Health and Fitness.However, our device is not a medical device and does not have a medical hardware regulatory license. How can I pass the audit?
“Hello,
The issues we previously identified still need your attention.
If you have any questions, we are here to help. Reply to this message in App Store Connect and let us know.
Review Environment
Submission ID: e5e36844-23e5-41fc-a956-eb46746728c1
Review date: April 16, 2024
Version reviewed: 1.0.1
Guideline 1.4.1 - Safety - Physical Harm
The app connects to external medical hardware to provide medical services. However, to be compliant with guideline 1.4.1, you must:
Provide documentation from the appropriate regulatory organization demonstrating regulatory clearance for the medical hardware used by the app.
Provide documentation of a report or peer-reviewed study that demonstrates the app's use of medical hardware works as described.
Restrict distribution of the app to regions where you have obtained regulatory clearance for the medical hardware used by the app. Otherwise, you must provide a jurisdiction statement in the app description declaring where the medical hardware has regulatory clearance to be used.
Update the app's description to include a disclaimer reminding users to seek a doctor’s advice in addition to using this app and before making any medical decisions.
Next Steps
To resolve this issue, provide the documentation requested above, restrict your salable storefronts in App Store Connect or include a jurisdiction statement in the app description, and update your app's description in App Store Connect to include the required medical disclaimer.
Resources
Learn more about requirements for medical apps in guideline 1.4.1.
Support
Reply to this message in your preferred language if you need assistance. If you need additional support, use the Contact Us module.
Consult with fellow developers and Apple engineers on the Apple Developer Forums.
Help improve the review process or identify a need for clarity in our policies by suggesting guideline changes.”
The WWDC23 session number 10016 is referring to a way to generate .workout files (timecode 09:43) in both binary and JSON format.
Unfortunately, the API seems to have changed:
CustomWorkoutComposition renamed to CustomWorkout
.dataRepresentation disappeared
Ideally I would like to generate .workout files directly in JSON format but there is no specifications published and no documentation to generate them.
Any idea where I should look?
Hi All,
I have a strange issue. I am using enableBackgroundDelivery for updating user step count in background mode using health kit. It works fine when I execute the app by pressing 'Run' in xcode. But the code is not triggering when I am directly launching it on my device. I have tried many different things but cannot figure out the issue from 2 days 😭. I would really appreciate any suggestions.
Thanks
Hello,
I am writing as I am seeing a very strange behavior when attempting to run an HKStatisticsCollectionQuery over multiple app starts.
Steps:
Initially load and launch my app into an iOS simulator (running iOS 17.2) via Xcode (version 15.3).
Execute code path which invokes the following method below.
Authorize necessary Read permission for the HKQuantityTypeIdentifierStepCount type.
Observed that a non-nil HKStatisticsCollection is returned in the initialResultsHandler, with corresponding expected datapoints. These datapoints are in no way stored or retained on the device at all.
Stop the app via Xcode.
Relaunch the app via Xcode.
Execute the same code path as in step 2.
Observed (via breakpoints) that even though the query is executed by the HKHealthStore, the initialResultsHandler is never called and no HKStatisticsCollection is ever returned.
Input parameters are the same in both instances of the call, and can confirm there is data in the devices HealthKit datastore.
I would expect, reading Apple's documentation, that both queries should execute and return the exact same datapoints in an HKStatisticsCollection, but please feel free to correct me if I am misunderstanding something, or if my code is incorrect in some way.
func fetchStatisticsCollection(with quantityType: HKQuantityType,
predicate: NSPredicate? = nil,
options: HKStatisticsOptions,
anchorDate: Date? = nil,
interval: DateComponents? = nil,
initialResultsCompletion: @escaping (Result<HKStatisticsCollection, Error>) -> Void,
updateHandler: (Result<HKStatisticsCollection, Error>) -> Void?) {
var statisticsQueryAnchorDate: Date = Date()
if let anchor = anchorDate {
statisticsQueryAnchorDate = anchor
} else if let yesterdayAnchor = createStaticsQueryAnchorDateYesterday(){
statisticsQueryAnchorDate = yesterdayAnchor
}
let dateInterval = interval ?? DateComponents(day: 1)
// Create the query
let query = HKStatisticsCollectionQuery(quantityType: quantityType,
quantitySamplePredicate: predicate,
options: options,
anchorDate: statisticsQueryAnchorDate,
intervalComponents: dateInterval)
// Set the results handler
query.initialResultsHandler = { query, results, error in
if let error = error as? HKError{
// Return wrapped HKError
initialResultsCompletion(.failure(HealthKitManagerError.hkError(error: error)))
return
}
guard let statsCollection = results else {
// Return custom Empty Results error.
initialResultsCompletion(.failure(HealthKitManagerError.emptyResults))
return
}
initialResultsCompletion(.success(statsCollection))
}
if let updateHandler = updateHandler {
query.statisticsUpdateHandler = { query, statistics, statisticsCollection, error in
if let error = error as? HKError{
// Return custom wrapped HKError.
updateHandler(.failure(HealthKitManagerError.hkError(error: error)))
return
}
guard let statsCollection = statisticsCollection else {
// Return custom Empty Results error.
updateHandler(.failure(HealthKitManagerError.emptyResults))
return
}
updateHandler(.success(statsCollection))
}
}
if activeTypeQueries[quantityType.identifier] == nil {
healthStore.execute(query)
activeTypeQueries[quantityType.identifier] = query
healthStore.enableBackgroundDelivery(for: quantityType, frequency: .immediate) { (success, error) in
if let error = error {
return
}
if success {
print("background enabled")
}
}
} else {
print("NOT executing query, we already have one query running for this type")
}
}
Thank you
Hello,
I am using the project from https://developer.apple.com/documentation/healthkit/workouts_and_activity_rings/building_a_multidevice_workout_app
The workout is starting on the watch and I can see the metrics, but it seems the mirroring with the phone is not working, I am getting this errors
[mirroring] <HKWorkoutSession:0x600002c10100 57C340BA-2AA9-4477-9AC8-181698A526A5 running [Primary]>: Failed to send data to remote session with error: Error Domain=com.apple.healthkit Code=300 "Remote device is unreachable" UserInfo={NSLocalizedDescription=Remote device is unreachable, NSUnderlyingError=0x600000c53b70 {Error Domain=RPErrorDomain Code=-6727 "kNotFoundErr ('rapport:rdid:PairedCompanion' not found)" UserInfo={cuErrorDesc=kNotFoundErr ('rapport:rdid:PairedCompanion' not found), cuErrorMsg='rapport:rdid:PairedCompanion' not found, NSLocalizedDescription=kNotFoundErr ('rapport:rdid:PairedCompanion' not found)}}}
Does anybody else has this issue?
Thank you
Hello,
I’m currently developing a fitness app for watchOS that lets a user to manually set a desired heart rate target zone (enter numbers representing the lower and upper boundaries) and start a workout (right now it’s only “Other” type).
After that my app monitors user’s heart rate and alerts them when they’re out of zone.
When user ends the workout, the info about this workout appears on “Fitness” iOS app, and user can see the workout data like Workout Time, Active and Total Calories, Avg. Heart Rate.
Also user can see Heart Rate chart with info how their heart rate was changing during a workout (see the Figure 1).
Now to the question.
When user clicks “Show More” button above the Heart Rate chart, they can see the same Heart Rate chart and another one, with Post-Workout Heart Rate (see the Figure 2).
But there is no “Estimated time in each heart rate zone” as one can see in the workout’s details that were recorded from Apple’s workout (watchOS “Workout” app, for a workout of “Other” type as well). Please see the Figure 3.
The question is: is it possible to add “Estimated time in each heart rate zone” to workout recorded via my third-party app so it would look like on the Figure 3 in "Fitness" iOS app, and if it's possible, what steps should I undertake to implement this ?
Thanks in advance!
I posted the screenshots in the replies to the post, because otherwise I was not able to submit a post ("sensitive language" warning, I suspect it's because of the ids in the attached screenshot's urls)
Our watchOS app uses CMFallDetectionManager (with the proper entitlement) to help alert our users and their caregivers when a fall occurs. We have had a simple implementation in our app for a couple of years now and it seems to work fine.
Recently, we received a report of delayed fall alerts and have traced back the root cause to a failure from the system to call func fallDetectionManager(_ fallDetectionManager: CMFallDetectionManager, didDetect event: CMFallDetectionEvent, completionHandler handler: @escaping () -> Void) promptly when a fall occurs.
Our implementation of this method begins with the following logging statement: "Fall detected at \(event.date) with status \(event.resolution.rawValue) at \(Date())"
When we check our logs, we see a number of events that occur as expected, for example: Fall detected at DATE_AND_HOURS:42:09 +0000 with status 1 at DATE_AND_HOURS:42:51 +0000
However, many events show a period of several minutes from fall detection to a report: Fall detected at DATE_AND_HOURS:28:09 +0000 with status 0 at DATE_AND_HOURS:32:42 +0000 or Fall detected at DATE_AND_HOURS:44:26 +0000 with status 1 at DATE_AND_HOURS:48:14 +0000
And in the instance from our customer, we had a fall detected that evidently wasn't reported for 5 hours and 4 minutes (I'm not sharing exact timestamps publicly to maintain user privacy).
We are aware of the documentation regarding the delegate and have programmed it appropriately not to receive duplicate events:
Additionally, each time the user launches your app, the system checks to see if a fall event has occurred during the recent past. If one has occurred, it calls this method.
Note that your app may receive the same event multiple times, for example, if the app crashes and relaunches. Always check the event’s date property to determine whether your app has already received the event. The system guarantees that different fall events have different date values.
Moreover, our logger persists logs when there is no network access, and the delegate callback also requests a network post to our servers that, again, is preserved in a background queue until connectivity is restored if it's not available. Our app's other updates (watchOS complication, etc.) from this user's Watch also show that our app was running in the background and communicating with our servers during that time. We have very high confidence that the watch and our app did not miss any more timely calls to that delegate method.
While this one five-hour delay was an exceptionally bad occurrence, we also find the other delays of several minutes to be concerning, considering the time-sensitive nature of falls. Does Apple or do any developers have any insights about what's going on and what expectations we should be setting for our users?
Hello,
I am developing an Apple Watch app in Swift and SwiftUI that needs to receive real-time heartbeat data to visualize the time intervals between heartbeats. The app draws circles on the screen where the size and position of each circle are based on the time interval between consecutive heartbeats.
I am currently using the HKQuantityType for .heartRate from HealthKit to get heart rate data and calculate the intervals. However, I am wondering if this is the best approach for my requirement. I came across the HKElectrocardiogram class, and I am not sure if it would be a better fit for obtaining real-time heartbeat intervals.
My questions are:
Real-Time Heartbeats:
Is HKQuantityType for .heartRate the most appropriate way to get real-time heartbeat data for calculating intervals between beats?
Can HKElectrocardiogram provide real-time heartbeat intervals, or is it more suited for detailed ECG recordings rather than instantaneous heartbeats?
Accuracy and Performance:
Which method provides the most accurate and real-time data for heartbeat intervals?
Are there any other APIs or services in the Apple Watch ecosystem that I should consider for this purpose?
Best Practices:
What are the best practices for implementing real-time heartbeat monitoring in an Apple Watch app?
Are there any sample projects or documentation that could help me understand the optimal way to achieve this?
Here is a brief overview of my current implementation using HKQuantityType for .heartRate:
import Foundation
import HealthKit
class HeartRateMonitor: NSObject, ObservableObject {
@Published var heartRate: Double = 0.0
@Published var intervals: [TimeInterval] = []
private var lastHeartRateTimestamp: Date?
private var healthStore: HKHealthStore?
private let heartRateQuantityType = HKObjectType.quantityType(forIdentifier: .heartRate)
private let appStartTime: Date
override init() {
self.appStartTime = Date()
super.init()
if HKHealthStore.isHealthDataAvailable() {
self.healthStore = HKHealthStore()
self.requestAuthorization()
}
}
private func requestAuthorization() {
guard let heartRateQuantityType = self.heartRateQuantityType else { return }
healthStore?.requestAuthorization(toShare: nil, read: [heartRateQuantityType]) { success, error in
if success {
self.startMonitoring()
}
}
}
func startMonitoring() {
guard let heartRateQuantityType = self.heartRateQuantityType else { return }
let query = HKAnchoredObjectQuery(
type: heartRateQuantityType,
predicate: nil,
anchor: nil,
limit: HKObjectQueryNoLimit) { (query, samples, deletedObjects, newAnchor, error) in
guard let samples = samples as? [HKQuantitySample] else { return }
self.process(samples: samples)
}
query.updateHandler = { (query, samples, deletedObjects, newAnchor, error) in
guard let samples = samples as? [HKQuantitySample] else { return }
self.process(samples: samples)
}
healthStore?.execute(query)
}
private func process(samples: [HKQuantitySample]) {
for sample in samples {
if sample.endDate > appStartTime {
let heartRateUnit = HKUnit.count().unitDivided(by: HKUnit.minute())
let heartRate = sample.quantity.doubleValue(for: heartRateUnit)
DispatchQueue.main.async {
self.heartRate = heartRate
if let lastTimestamp = self.lastHeartRateTimestamp {
let interval = sample.endDate.timeIntervalSince(lastTimestamp)
self.intervals.append(interval)
}
self.lastHeartRateTimestamp = sample.endDate
}
}
}
}
}
Thank you for your guidance and suggestions!
Are there any changes in the frequency of HRV samples the Apple Watch takes in watchOS 11? Currently sample rates are very low except for users who have Afib History turned on. There should be some other way for users to get the benefit of more HRV sampling per day without needing to turn Afib History on if they haven't been diagnosed with Afib.
Also is it possible for a 3rd party app to trigger an HRV sample?
Thanks!
Gary
The session Build custom swimming workouts with WorkoutKit mentions Outdoor activities supporting distance goals and lists:
Cycling
Running
Hiking
Walking
Swimming
Wheelchair walk + run
And new:
Golf
Rowing
Downhill skiing
Snowboarding
Lacrosse
Hockey
Disc Sports
Skating
Paddle sports
Soccer
American football
Australian football
Rugby
Cross country skiing
I know the previous 6 have GPS tracks saved with the workout in Health.
Do all of the other ones now also save the GPS track to Health?
If not all of them, which do?
In the Explore Wellbeing APIs in HealthKit video, developers are referred to the documentation for more information. However, like most APIs in recent years, there doesn't seem to be any documentation. Can someone please clarify what specifically the video references?
Explore Wellbeing APIs in HealthKit:
First, let’s start with some terminology. The GAD-7 and PHQ-9 are standardized questionnaires that are made available by Pfizer. They’re used by doctors and clinicians around the world for mental health screening. The GAD-7 consists of 7 questions to assess a person’s risk of anxiety and the PHQ-9 consists of 9 questions to assess risk of depression.
This year, you’ll be able to read and write the results of the GAD-7 anxiety and PHQ-9 depression questionnaires. With these new data types, people can check in on efficacy of treatment, or save the results from their doctor's office.
It’s important to give these assessments in accordance with Pfizer’s standards, so check out our developer documentation to learn more.
It's fairly well know and stated that the Apple Health / HealthKit data store is unavailable when iPhone is locked.
Since Lock Screen Widgets were introduced there's been a feature parity mismatch with Apple's own Fitness app which is able to display updating Activity Rings on the Lock Screen. Third party apps cannot do this and have to rely unlocking their device to then trigger an update. This means they often display stale and wrong Health data.
With the release of iOS 18 beta, I see no changes to this... Is there anything I've missed?
Currently for requesting the Timeline Updates on my Widget I have to just keep requesting updates as often as possible and hope that each time the iPhone might be unlocked.... This is inefficient and a waste of device resources. Even a Widget timeline reload API that let the developer say "Only call update if iPhone unlocked" would be useful.
Hi everyone,
With iOS 18 and watchOS 11 it is possible to pause your activity rings so that a streak is not broken when you are ill or something like that.
When we request data from the HealthStore, is there a way to know that a user has set this option for a particular date or period?
Or will the data for that date just return nil for all 3 ring values or even skip the day in the dataset?
I have an app in which I also keep track of people's streaks, so it would really useful to know if the activity rings are paused.
Thanks in advance!
This has long been a frustration of mine on Apple Watch, and I've brought it up at WWDC labs every year to no avail but while the limitation on the Apple Watch to only be able to query 7 days of HealthKit data may have made sense early in the AW's lifetime for battery preservation etc., it really no longer makes sense in modern AW development.
Especially not with stand alone watch apps, as a developer I am prohibited from building the same experience on the Apple Watch that I can in an iPhone app. For example, my app looks at your current health metrics and compares them to your 60 day baseline to identify any deviations from your normal ranges. I cannot create the same experience on the watch using purely HealthKit queries, and am limited to using either iCloud or Watch Connectivity which have their own drawbacks and are not an option for a stand alone watch app.
Can we finally expand the length of HealthKit queries the AW can make so that we can build the same powerful experience on the watch that we can on iPhone?
Thank you!
Gary
See also Feedback FB7649612 (from April 2020).