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

Posts under Health & Fitness subtopic

Post

Replies

Boosts

Views

Activity

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
314
Nov ’24
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
323
Nov ’24
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
615
Nov ’24
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
700
Nov ’24
car accident detect API
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
2
0
417
Jan ’25
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
5
0
1.1k
Dec ’24
Change displayed metric in Fitness app
Good afternoon, I am working on a workout tracking app. So far everything is working as expected. However, I note that when my workout saves and is visible within the Fitness App, the workout duration is displayed rather than the kCal burned. What changes are required to be made in order for this to display the kCal in the list of workouts in Fitness rather than duration? For reference https://developer.apple.com/videos/play/wwdc2021/10009 this was my reference source for workout functionality.
1
0
905
Jan ’25
When does appleExerciseTime update or change?
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.
2
0
892
Jan ’25
HealthKit returns different values depending on the OS the request is made on
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) }
4
0
1k
Jun ’25
Read Workout Effort Scores
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
2
0
911
Jan ’25
Can't properly check if Health Kit is authorized.
In my WatchOS app I've written the following code to check if my app has access to the user's health data: func isHealthKitAuthorized() -> Bool { let typesToRead: [HKObjectType] = [ HKObjectType.quantityType(forIdentifier: .heartRate)!, HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)!, HKObjectType.quantityType(forIdentifier: .appleMoveTime)!, HKObjectType.quantityType(forIdentifier: .appleExerciseTime)!, HKObjectType.workoutType() ] let typesToShare: Set<HKSampleType> = [ HKObjectType.workoutType(), HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)!, HKObjectType.quantityType(forIdentifier: .heartRate)! ] var isAuthorized = true for type in typesToRead { let status = healthStore.authorizationStatus(for: type) if status != .sharingAuthorized { print("Access denied to: \(type.identifier)") isAuthorized = false } } for type in typesToShare { let status = healthStore.authorizationStatus(for: type) if status != .sharingAuthorized { print("Access denied to: \(type.identifier)") isAuthorized = false } } return isAuthorized } However for the appleMoveTime and appleExerciseTime types their status is returning as 'sharingDenied' (checked by printing the status' rawValue) even though they are authorized on the Watch's settings. This happened both on the simulator and on the Watch itself. Am I doing something wrong?
1
0
802
Jan ’25
Can I use an HKQueryAnchor across multiple devices?
Hello, I am currently working on an app that uses HealthKit to sync health data to a backend server that performs analysis on this data. I am keeping track of the synced data with the HKQueryAnchor I receive for each query I make. I want to address an edge case: if a user has multiple devices running the app, would it make sense to store the anchor on my backend? This would ensure that other instances of the app do not sync data that has already been synced from another device. Thank you for your help!
1
0
786
Jan ’25
Is sleep analysis data available in Smart Alarms?
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!
5
0
888
Jan ’25
Can't create energy goals in WorkoutKit
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?
2
0
795
Jan ’25
Location of indoor workouts
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?
2
0
799
Apr ’25
App's domain being blocked/rerouted by Apple
I have a strange situation and I'm not sure where else to post this. Our app's domain (or at least its API hostname in the domain) resolves to something different only inside of Apple's network. I was able to get an Apple employee to verify this by resolving the API hostname while on Apple's corporate network and it resolves to an IP that is in Apple's 17.0.0.0/8 network, but everywhere else resolves to the normal IPs. Our domain's DNS is provided by Cloudflare and they are not doing anything special for Apple's network. This is causing problems during App Review because the app is trying to reach our API to log in and instead is being routed to an IP in Apple's network, so it fails SSL validation and presents an error dialog. App Review is then claiming our app doesn't work and rejecting it. This is an app that has been in the App Store for over a decade and gone through countless app reviews. App Review was of no help resolving this and I don't know where else to turn. How can I find out why our domain is being rerouted inside of Apple and get this fixed?
3
0
505
Feb ’25
HealthKit: Seeking Guidance on Continuous, Near Real-Time Heart Rate Data Conitnously in IOS Application
Dear Apple Developer Support, I am writing to request assistance with an ongoing issue I'm encountering while developing an iOS application that utilizes HealthKit to fetch heart rate data. My goal is to display near real-time heart rate updates continuously same as displaying in the Apple Watch , I want to show in the iPhone Mobile Application for fitness related. I have implemented the following approaches: HKSampleQuery with a Timer: I've set up a timer to periodically fetch the latest heart rate data. Despite these efforts, I'm consistently facing the following problems: Delayed Updates: The heart rate data displayed in the app often doesn't reflect the current heart rate being measured by the Apple Watch. There seems to be a significant synchronization delay. Inconsistent Background Updates: Background updates, even with background app refresh enabled, are not reliable. The app often only updates when brought to the foreground or after being killed and relaunched. Entitlements: The com.apple.developer.healthkit.background-delivery entitlement error is missing. I have thoroughly reviewed Apple's HealthKit documentation, implemented best practices for HealthKit integration, and verified that all necessary permissions are properly configured. I understand that HealthKit may not be designed for true real-time data, but the current level of delay and inconsistency is making it difficult to provide a useful user experience. Could you please provide guidance on whether achieving near real-time heart rate updates continuously in an iOS app using HealthKit is possible? If so, what are the recommended strategies and best practices to overcome these limitations? I have also tested the application on physical devices with Apple Watch, enabled background app refresh, granted permissions, and referred to HealthKit documentation. I would appreciate any insights or suggestions you can offer to help resolve this issue. Thank you for your time and assistance. Sincerely, Venu Madhav
1
0
689
Feb ’25
Is it possible to provide an interface for real-time sleep status monitoring
Apple Watch automatically tracks sleep data and syncs it to the iPhone, making it available through HealthKit for historical analysis. However, there is no way to retrieve real-time data on whether a user has entered sleep, or whether they are in a specific sleep stage at any given moment. Is it possible to provide an interface for real-time sleep status monitoring
1
0
556
Feb ’25
Integrating Apple Fitness+ Workouts – How to Retrieve Metadata?
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!
4
0
599
Feb ’25