Search code examples
iosswifthealthkit

How to detect if HealthKit data is set from a device?


I'm trying to fetch user steps from HealthKit and realised that users can add manually steps which I don't want to fetch. (For instance if they're cheating and setting 50k steps on one day).

So I was thinking for a solution how to solve this problem and found out that maybe I could just filter all the result and fetch the data if the data was set by a device. I mean it could be set by an iPhone, but it can also be set by an Apple Watch.

Here's how it looks when a user adds his/hers own steps manually in the Health app:

Steps added by an user

Here's how it looks when the steps are added by a device:

Steps added by a watch

So when the data are set by a device, we can see more information from the device in the Health-app rather than a user whom setting the data manually.

The question is: How do I find if there are a device in the result?

My current code to fetch the results:

func getSteps(completion: @escaping (Double, Error?) -> ()) {
    let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount)!
           
    let query = HKSampleQuery(sampleType: stepsQuantityType, predicate: nil, limit: 0, sortDescriptors: nil){ query, results, error in
        if let error = error {
            // Handle error
        } else if let results = results, !results.isEmpty {
            for result in results {
                // Detect and add result if result is from a device
            }
        }
    }

    HKHealthStore().execute(query)
}

Solution

  • I just realised that I can detect if a device does exist by result.device where device is an optional value. By doing so I can check if the value is nil or not.

    func getSteps(completion: @escaping (Double, Error?) -> ()) {
        let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount)!
    
    
        let query = HKSampleQuery(sampleType: stepsQuantityType, predicate: nil, limit: 0, sortDescriptors: nil){ query, results, error in
            if let error = error {
                // Handle error
            } else if let results = results, !results.isEmpty {
                for result in results {
                    if result.device != nil {
                        // Result is from a device
                    } else {
                        // Not a device
                    }
                }
            }
        }
    
        HKHealthStore().execute(query)
    }