Health & Fitness

RSS for tag

Explore the technical aspects of health and fitness features, including sensor data acquisition, health data processing, and integration with the HealthKit framework.

Health & Fitness Documentation

Post

Replies

Boosts

Views

Activity

Deprecated: HKCategoryValueMenstrualFlow
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?
2
1
108
2d
HealthKit SDK Not Responding When Querying Step Data on iPhone 16 Pro Max
We have working code to fetch step data from HealthKit after requesting the necessary permissions. However, we’ve encountered an issue specific to one device, the iPhone 16 Pro Max. When querying the data, we do not receive a response, and the code enters an infinite loading state without completing the request. The user who is facing this issue has tried logging in on another device, and it works fine. On the problematic device (iPhone 16 Pro Max), the request does not complete. For reference, I’ve included the code below. Resolving this issue is crucial, so we would appreciate any guidance on what steps we can take to troubleshoot or resolve the problem on this specific device. Please note that the device has granted permission to access HealthKit data. static let healthStore = HKHealthStore() static func limitReadFromHealthKitBetweenDates(fromDate: Date, toDate: Date = Date(), completion: @escaping ([HKStatistics]) -> Void) { guard let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount) else { return } let ignoreUserEntered = HKQuery.predicateForObjects(withMetadataKey: HKMetadataKeyWasUserEntered, operatorType: .notEqualTo, value: true) let now = toDate var interval = DateComponents() interval.day = 1 var calendar = Calendar.current calendar.locale = Locale(identifier: "en_US_POSIX") var anchorComponents = calendar.dateComponents([.day, .month, .year], from: now) anchorComponents.hour = 0 let anchorDate = calendar.date(from: anchorComponents) ?? Date() let query = HKStatisticsCollectionQuery(quantityType: stepsQuantityType, quantitySamplePredicate: ignoreUserEntered, options: [.cumulativeSum], anchorDate: anchorDate, intervalComponents: interval) query.initialResultsHandler = { _, results, error in guard let results = results else { print("Error returned from resultHandler: \(String(describing: error?.localizedDescription))") return } print(results) var statisticsArray: [HKStatistics] = [] results.enumerateStatistics(from: fromDate, to: now) { statistics, _ in statisticsArray.append(statistics) if statistics.endDate.getddmmyyyyslashGMT == now.getddmmyyyyslashGMT { completion(statisticsArray) } } } healthStore.execute(query) } Please note that the code works on all devices except the problematic one. Could you please guide me on the next steps to resolve this issue?
0
0
81
3d
Workout mode drains battery heavily
I am building a watchOS app with iOS companion app. The watch app needs to track the heart rate during the night or while user is sleeping. And the desired frequency of measurement is 0.2Hz (every 5 seconds) For this I am using the HKWorkout mode with mindAndBody session. While it works fine, One of the main issue is: after about 6-7 hours of usage, the battery on the watch drains between 40% (Series 9) and 100% (series 7, I think) My questions: Are there any other option to track user's heart rate without workout, while the app could be in background? Another side effect of this workout mode is, Even if we choose not to save the workout in HealthKit, the Activity rings gets populated by this mindAndBody session, which makes it when the user is waking up, the bar is already full, This is not desired. Is there any option to specify for ActivityRing skips this? Highly appreciate any help in advance. Cheers - Prakash
4
0
177
4d
User-Entered Sleep Data Lacks Time Zone
As a user, there are times when I don't wear my sleep tracker to bed, but I nonetheless want to record my sleep times. Apple Health supports this with the "Add Data" feature, but it's not possible to provide a time zone in the form. Then as a developer, user-added sleep samples are missing time zone information. I would expect that the time zone is requested within the Add Data form. Without this information provided at input time, downstream applications are forced to infer the time zone ourselves, leading to potentially buggy or unintuitive behavior.
0
0
85
1w
apple watch as FREE diving watch
good morning every one, hopefully this is the right place where to speak. I am not a developer and I am not familiar with and programming. I am a simple apple user and happend to me that my diving watch died few weeks ago. Since then I am using Apple Watch Ultra to free dive and spare fishing. Honestly we few small modifications this watch can take the lead over Garmin and Suunto that at the moment are the two best watch on the market for this specific area. will it be possible to give some feedbacks and develop the app? many Thanks Mickey
1
0
89
1w
Issue with HealthKit Read Permissions on iOS App vs. WatchKit Extension
I'm encountering an issue with HealthKit permissions and would appreciate some guidance: In my app's previous version, I granted write permissions for HKObjectType.workoutType() via the WatchKitExtension. Now, in the upcoming version, I'm trying to request read permissions for both HKObjectType.workoutType() and HKSeriesType.workoutRoute() via the iOS app. However, after granting access: The read permissions for Workout and Workout Route don't show up under Settings -> Health -> Data and Access -> [My App]. The Workout Route permission status remains notDetermined, even though I selected "Allow" when prompted. Interestingly, if I request the same permissions via the WatchKitExtension, everything works as expected, and the issue doesn't occur. Has anyone experienced a similar issue or have insights into why this might be happening? Could it be related to requesting permissions from the iOS app instead of the WatchKitExtension?
0
0
126
2w
Why do we still have the 7 day limitation of HealthKit data on Apple Watch?
It may have made sense in the early days of watchOS, but given the Apple Watch is now 10 years old and we have "Standalone" Apple Watch apps, it no longer makes sense to have this seemingly arbitrary limitation of only being able to query 7 days of data on the watch. I have an open feedback (FB7649612) from 2020 with no responses and ask this question every year at WWDC Developer labs. WHY must we still deal with this limitation which only causes other developers to store critical health data in iCloud or on their own servers in order to provide a robust stand alone watch experience on the Apple Watch. Even Apple themselves must either use a separate private API or use iCloud for the new Vitals app. How else can I escalate this request?
1
1
190
2w
CMAltimeter not delivering relative altitude updates
I want to get the barometric pressure reading from the built-in barometer to display it in my iOS app. When I use CMAltimeter.startRelativeAltitudeUpdates(), my app receives no relative altitude update events, which means I can't view the barometric pressure from the sensor (because that's only contained in CMAltitudeData, not CMAbsoluteAltitudeData. If I use CMAltimeter.startAbsoluteAltitudeUpdates(), I get absolute altitude update events every second or so. NSMotionUsageDescription is set. I have tried the following things, all of which haven't worked: Only calling startRelativeAltitudeUpdates() and not startAbsoluteAltitudeUpdates() Calling CMSensorRecorder.recordAccelerometer(forDuration: 0.1), as suggested in this thread Calling CMMotionActivityManager.queryActivityStarting(from: .now, to: .now, to: .main), as suggested here Physically moving my iPhone up and down about 200 feet using an elevator; I see absolute altitude updates which are in line with what's expected, but still receive no relative altitude update events Calling the same APIs in a watchOS app on an Apple Watch Series 10; I see much less frequent absolute altitude updates, and still no relative altitude updates I know the barometer sensor is working, because when I move my iPhone up and down even a foot or two indoors, I see an immediate change in the absolute altitude reading that I know wouldn't come from GPS. This example code, when run on my iPhone 16 Pro running iOS 18.1.1, prints updates started and then updating absolute every second, but doesn't print anything else. The absolute altitude, accuracy, and authentication status fields update (and the auth status shows 3, indicating .authorized), but the relative altitude and pressure fields remain as --. struct ContentView: View { @State private var relAlt: String = "--" @State private var relPressure: String = "--" @State private var absAlt: String = "--" @State private var precision: String = "--" @State private var accuracy: String = "--" @State private var status: String = "--" var body: some View { VStack { Text("Altitude: \(relAlt) m") .font(.title3) Text("Pressure: \(relPressure) kPa") .font(.title3) Text("Altitude (absolute): \(absAlt) m") .font(.title3) Text("Precision: \(precision) m") .font(.title3) Text("Accuracy: \(accuracy) m") .font(.title3) Text("Auth status: \(status)") .font(.title3) } .padding() .onAppear { let altimeter = CMAltimeter() startRelativeBarometerUpdates(with: altimeter) startAbsoluteBarometerUpdates(with: altimeter) status = CMAltimeter.authorizationStatus().rawValue.formatted() print("updates started") } } private func startRelativeBarometerUpdates(with altimeter: CMAltimeter) { guard CMAltimeter.isRelativeAltitudeAvailable() else { relAlt = "nope" relPressure = "nope" return } altimeter.startRelativeAltitudeUpdates(to: .main) { data, error in if let error = error { print("Error: \(error.localizedDescription)") return } if let data = data { print("updating relative") relAlt = String(format: "%.2f", data.relativeAltitude.doubleValue) relPressure = String(format: "%.2f", data.pressure.doubleValue) } else { print("no data relative") } } } private func startAbsoluteBarometerUpdates(with altimeter: CMAltimeter) { guard CMAltimeter.isAbsoluteAltitudeAvailable() else { absAlt = "nope" print("no absolute available") return } let altimeter = CMAltimeter() altimeter.startAbsoluteAltitudeUpdates(to: .main) { data, error in if let error = error { print("Error: \(error.localizedDescription)") return } if let data = data { print("updating absolute") absAlt = String(format: "%.2f", data.altitude) precision = String(format: "%.2f", data.precision) accuracy = String(format: "%.2f", data.accuracy) } } } } Is this behavior expected? How can I trigger delivery of relative altitude updates to my app?
1
0
208
3w
Cannot get Custom Workout to show up on Apple Watch
I started with the custom workout example from Apple. I was able to load the apps from my mac (xcode) to my iphone. I can run the apps on my iphone. I completed the authorization and reviewed the workout. I then uploaded the workout to the watch and it appeared to work. It never showed up on the watch. I tried restarting the watch and iPhone. I have. a second watch and I tried that. Nothing helped. IPhone 14 with ios 18.2. Watch is Series 6 with watch OS 11.2. I also tried it with the watch on the charger but no change. Workout Kit seems like a good idea, but not if you cannot get it on your watch. It seems very few people are using it as there is little info online.
0
0
117
3w
How to export workout plan as JSON?
Hi guys, In WWDC23 session 10016: Build custom workouts with WorkoutKit , the presenters mentioned that a Workout Plan can be exported to a JSON or binary file, and also showed a code snip: let binaryRepresentation = try myCyclingWorkout.dataRepresentation(in: .compactBinary) However in the current SDK, the property dataRepresentation can not be exported with a specific format, the base64EncodedString() result is unreadable. Does anyone know how to export it as a JSON string now? Thanks very much.
0
0
129
3w
Device Activity Report Per hour Screen-time of apps for Graph
Hi everyone, I need to display a Graph based on Screen-time of apps per hour, from 12Am to 11PM. Am able to get the screen-time data for whole day with each app's total screen-time value. Am kind of confused how can I get the per hour screen-time of apps. I have applied filter of day DeviceActivityFilter( segment: .daily( during: Calendar.current.dateInterval( of: .day, for: .now )! ), users: .all, devices: .init([.iPhone, .iPad]) ) Am also using this data to display apps with their usage just like Apple's Screen_time in settings. I need to display exact same graph just like Apple's screen in phone settings for a Day.
1
0
139
3w
HKStatisticsCollectionQuery or HKStatisticsCollectionQueryDescriptor
Hi, there seems to be two methods to fetch data from HealthKit and calculate statistics on intervals of the data; HKStatisticsCollectionQuery and HKStatisticsCollectionQueryDescriptor. I am currently using HKStatisticsCollectionQuery, but HKStatisticsCollectionQueryDescriptor seems to do the same, but with very different code setup. Could anyone provide any advice on which method is preferable? Will the older HKStatisticsCollectionQuery become obsolete in the near future? Thanks Tommy
1
0
125
3w
Proper method to handle error in statisticsUpdateHandler?
In my app the the statisticsUpdateHandler fetches data from the HealthKit when I open the app from sleeping/standby state. This works fine, except when I leave the app running in the foreground and close the phone for an extended period. This triggers the .errorDatabaseInaccessible error. This seems to stop the statisticsUpdateHandler, maybe set it to nil or something similar. What is the proper way to handle the error to keep it running? As shown in the code below I have tried setting the completion data to the current data. But it stills seems to exit, and thus require a complete restart of the app to re-register the update handler. Thanks Tommy Task { do { try await healthStore.requestAuthorization(toShare: [], read:healtTypes) fetchPast14daysData() } catch { print("Error requesting access to health data") } } func fetchDiscreteData(startDate: Date, type: HKQuantityTypeIdentifier, completion: @escaping([WorkoutMetric]) -> Void) { let datatype = HKQuantityType(type) let interval = DateComponents(day: 1) let query = HKStatisticsCollectionQuery(quantityType: datatype, quantitySamplePredicate: nil, options: .discreteAverage, anchorDate: startDate, intervalComponents: interval) query.initialResultsHandler = { query, result, error in ... } query.statisticsUpdateHandler = { query, statistics, result, error in var lock_error_detected: Bool = false // Handle errors here. if let error = error as? HKError { switch (error.code) { case .errorDatabaseInaccessible: lock_error_detected = true default: // Handle other HealthKit errors here. DispatchQueue.main.async { self.update_error = error.userInfo[NSLocalizedDescriptionKey] as? String } return } } var data = [WorkoutMetric]() if lock_error_detected { if (type == .heartRateVariabilitySDNN) { data = self.HRV } else { data = self.restingPulse } } else { guard let result = result else { completion([]) return } result.enumerateStatistics(from: startDate, to: Date()) { statistics, stop in if ( type == .heartRateVariabilitySDNN) { let value = Float(statistics.averageQuantity()?.doubleValue(for: .secondUnit(with: .milli)) ?? 0.0) //print("HRV data \(value)") if (value > 1) { data.append(WorkoutMetric(date: statistics.startDate, Value: value, Average: 0.0)) } } else if ( type == .restingHeartRate) { let value = Float(statistics.averageQuantity()?.doubleValue(for: .hertzUnit(with: .none)) ?? 0.0) //print("Resting hearth rate : \(value) at date \(statistics.startDate)") if (value > 0.01) { data.append(WorkoutMetric(date: statistics.startDate, Value: value*60, Average: 0.0)) } } } let _ = calculate_average(days: self.averagePeriod, workouts: &data) } completion(data) } healthStore.execute(query) } extension HealthManager { func fetchPast14daysData() { fetchCumulativeData(startDate: Date().daysAgoAligned(days: daysToFetchDataFor), type: .distanceWalkingRunning) { dailyDistance in DispatchQueue.main.async { self.distanceData = dailyDistance } .. ..
1
0
123
3w
Apple Watch 8 OS11.2 not synching my activity (intermittently)
My Apple Watch after the beta update is not syncing the activities sometimes with Apple Health. I just completed a 2.5 km walk, and it showed on Apple Health, yes, but it did not affect my daily goals. This is not the first time this has happened; this is just one of the examples that I'm sharing, other than what has been some problems that I am seeing after the beta update. Additionally, the camera remote app is not working correctly as I cannot see anything on the watch screen like I used to.
0
0
127
4w
incomplete route data in Apple Health
When we upload workout data to HealthKit the route information with the workout detailed data is incomplete: just a few dots. When we select "Show all workout routes" the route data for the same workout shows correctly. We use the HKWorkoutBuilder to store the workout data, and add the location data with the HKWorkoutRouteBuilder to the workout with Is this an Apple Health issue, or do we have to change something in the way we store the location data to the workout?
1
0
105
4w
HKWorkoutSession.sendToRemoteWorkoutSession doesn't report success or failure
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?
0
0
199
4w
watchOS app workout doesn't launch
I am creating a watchOS app with XCode, and am experiencing an issue where workouts do not start on watchOS versions 9.6.3 and later. ・App specifications Start workout when app starts code (swift) workout?.startActivity(with: Date()) ·phenomenon In watchOS version 9.6.3 or later, after the Apple Watch runs out of battery or is turned off. When you turn on your Apple Watch and start using it, even if you start a workout (startActivity),The status may not change to running and the workout may not work. *Workout always worked on watchOS versions earlier than version 9.6.3. *The workout will work if you close the app and start the app again. If anyone has any information, please provide it.
0
0
137
Nov ’24