We are using HealthKit in our app to synchronize step count data.
The data is correctly synced with the Health app, but the step count does not appear in the Fitness app (although workout data does).
Is there anything developers need to do to synchronize step count data with the Fitness app as well?
                    
                  
                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
                    
                      I'm developing a single target watchOS app that obtains HealthKit information. I have the "Background Delivery" option checked under "Signing & Capabilities" for the watch target. The app does HKObserverQueries in the foreground that work as I would expect. But when I click the Digital Crown to return to clock face, the HKObserverQuery activity stops. I'm using Xcode 15.4, on Mac 14.5 and a Apple Watch Series 4 running 10.5.
                    
                  
                
                    
                      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
}
..
..
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		Health & Fitness
		
  	
                  
                
              
              
              
  
  
    
    
  
  
              
                
                
              
            
          
                    
                      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
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		Health & Fitness
		
  	
                  
                
              
              
              
  
  
    
    
  
  
              
                
                
              
            
          
                    
                      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.
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		Health & Fitness
		
  	
                  
                
              
              
                Tags:
              
              
  
  
    
      
      
      
        
          
            Family Controls
          
        
        
      
      
    
      
      
      
        
          
            Device Activity
          
        
        
      
      
    
      
      
      
        
          
            Screen Time
          
        
        
      
      
    
  
  
              
                
                
              
            
          
                    
                      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?
                    
                  
                
                    
                      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
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		Health & Fitness
		
  	
                  
                
              
              
              
  
  
    
    
  
  
              
                
                
              
            
          
                    
                      Hello, we want to re-create these graphs and use the raw data for analysis.
We are getting aggregated elevation, heath rate, and pace data, but need to locate the specifics to create these graphs.
Thank you
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		Health & Fitness
		
  	
                  
                
              
              
              
  
  
    
    
  
  
              
                
                
              
            
          
                    
                      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
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		Health & Fitness
		
  	
                  
                
              
              
                Tags:
              
              
  
  
    
      
      
      
        
          
            Watch Connectivity
          
        
        
      
      
    
      
      
      
        
          
            HealthKit
          
        
        
      
      
    
      
      
      
        
          
            Battery Life
          
        
        
      
      
    
  
  
              
                
                
              
            
          
                    
                      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.
                    
                  
                
                    
                      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.
                    
                  
                
                    
                      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)
	}
                    
                  
                
                    
                      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
                    
                  
                
                    
                      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?
                    
                  
                
                    
                      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!
                    
                  
                
                    
                      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 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?
                    
                  
                
                    
                      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?
                    
                  
                
                    
                      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?
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		Health & Fitness
		
  	
                  
                
              
              
              
  
  
    
    
  
  
              
                
                
              
            
          
                    
                      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