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)
	}
Answered by DTS Engineer in 820471022

There are several reasons that can lead to a different query result on an iPhone and its paired Apple Watch:

  • The HealthKit store on the watch is a subset of the one on the iPhone. Typically, an Apple Watch only stores data within one week (or slightly longer), while an iPhone doesn't have the limit.

  • The HealthKit stores on the watch and iPhone don't synchronize in real time. Even your query doesn't span a long period, the result may be different if the data on the watch doesn't completely synchronize to the iPhone yet.

  • The HealthKit store on iPhone has data from different sources (devices or apps). HKStatisticsQuery does de-duplicate the data, but the result on the iPhone may include data that are not overlapped from other sources.

To get to the bottom of the issue, you can use HKSampleQuery + the same prediate to grab the samples from your watch and iPhone, and look into the result set to figure out the difference. Note that this is for debugging purpose. You will still use HKStatisticsQuery to query the data because it de-duplicates the data from different sources for you.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Accepted Answer

There are several reasons that can lead to a different query result on an iPhone and its paired Apple Watch:

  • The HealthKit store on the watch is a subset of the one on the iPhone. Typically, an Apple Watch only stores data within one week (or slightly longer), while an iPhone doesn't have the limit.

  • The HealthKit stores on the watch and iPhone don't synchronize in real time. Even your query doesn't span a long period, the result may be different if the data on the watch doesn't completely synchronize to the iPhone yet.

  • The HealthKit store on iPhone has data from different sources (devices or apps). HKStatisticsQuery does de-duplicate the data, but the result on the iPhone may include data that are not overlapped from other sources.

To get to the bottom of the issue, you can use HKSampleQuery + the same prediate to grab the samples from your watch and iPhone, and look into the result set to figure out the difference. Note that this is for debugging purpose. You will still use HKStatisticsQuery to query the data because it de-duplicates the data from different sources for you.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

My Watch App requires all of the data to work, so would the best way of getting all the data be through using the WatchConnectivity framework, getting the iPhone to request and then send to the watch?

I don't know how your apps work, but a typical pattern is to have the iOS app do the heavy-lifting and pass only the result to the watchOS app, because an iPhone is more powerful in many ways, and yes, you can use WatchConnectivity for the communication between the apps.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

HealthKit returns different values depending on the OS the request is made on
 
 
Q