skip to Main Content

I want to get the step data of a user by using HealthKit. However, I want to make sure that data that has been entered manually is ignored. I found a solution where someone asked this question and I know what needs to be entered but I am unsure how to do this. Wherever I put this code I seem to get errors:

Here is my code:

   func calculateSteps(completion: @escaping (HKStatisticsCollection?)-> Void) {
        
        let stepType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
        
        let startDate = Calendar.current.date(byAdding: .day, value: -7, to: Date())
        
        let anchorDate = Date.mondayAt12AM()
        
        let daily = DateComponents(day: 1)
        
        let predicate = HKQuery.predicateForSamples(withStart: startDate, end: Date(), options: .strictStartDate)
        
        query = HKStatisticsCollectionQuery(quantityType: stepType, quantitySamplePredicate: predicate, options: .cumulativeSum, anchorDate: anchorDate, intervalComponents: daily)
        
        query!.initialResultsHandler = { query, statisticsCollection, error in
            completion(statisticsCollection)
            
        }
        
        if let healthStore = healthStore, let query = self.query {
            healthStore.execute(query)
        }
    }

And this is the sort of code I need to implement in the predicate part.

let predicate = NSPredicate(format: "metadata.%K != YES", HKMetadataKeyWasUserEntered)

Where shall I put this code?

UPDATED:
I have the code running with no errors however when the function runs it comes out as 0. Any ideas?

import Foundation
import HealthKit

extension Date {
    static func mondayAt12AM() -> Date {
        return Calendar(identifier: .iso8601).date(from: Calendar(identifier: .iso8601).dateComponents([.yearForWeekOfYear, .weekOfYear], from: Date()))!
    }
}

class HealthStore {
    
    var healthStore: HKHealthStore?
    var query: HKStatisticsCollectionQuery?
    
    init() {
        if HKHealthStore.isHealthDataAvailable() {
            healthStore = HKHealthStore()
            
        }
    }

    func calculateSteps(completion: @escaping (HKStatisticsCollection?)-> Void) {
        
        let stepType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
        
        let startDate = Calendar.current.date(byAdding: .day, value: -7, to: Date())
        
        let anchorDate = Date.mondayAt12AM()
        
        let daily = DateComponents(day: 1)
        
       
        
        let predicate = HKQuery.predicateForSamples(withStart: startDate, end: Date(), options: .strictStartDate)
        let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates:
                                    [.init(format: "metadata.%K == NO", HKMetadataKeyWasUserEntered), predicate]
                                )
        query = HKStatisticsCollectionQuery(
           quantityType: stepType,
           quantitySamplePredicate: compoundPredicate,
           options: .cumulativeSum,
           anchorDate: anchorDate,
           intervalComponents: daily)
        
             
        
        query!.initialResultsHandler = { query, statisticsCollection, error in
            completion(statisticsCollection)
            
        }
        
        if let healthStore = healthStore, let query = self.query {
            healthStore.execute(query)
        }
    }
    
    func requestAuthorization(completion: @escaping (Bool) -> Void) {
        
        let stepType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
        
        guard let healthStore = self.healthStore else { return completion(false) }
        
        healthStore.requestAuthorization(toShare: [], read: [stepType]) { (success, error) in
            completion(success)
        }
    }
}

3

Answers


  1. I would try to create an NSCompoundPredicate with both the predicates you want and use that while creating the query.

    If you are still running into errors, please share the specific errors you see.

    Login or Signup to reply.
  2. Create a compound predicate with your current predicate

    let predicate = HKQuery.predicateForSamples(withStart: startDate, end: Date(), options: .strictStartDate)
    let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates:
                                [.init(format: "metadata.%K == NO", HKMetadataKeyWasUserEntered), predicate]
                            )
    query = HKStatisticsCollectionQuery(
       quantityType: stepType,
       quantitySamplePredicate: compountPredicate,
       options: .cumulativeSum,
       anchorDate: anchorDate,
       intervalComponents: daily)
    
    Login or Signup to reply.
  3. You need to create one Compound Predicate with the current Predicate as sub Predicate. And in format set metadata.%K != YES (metadata.%K == NO will not work here, because the value for the key could be YES, NO, or nil and nil implies NO).

    And then create a query using that Compound Predicate.

    Here is the code Sample

    let stepType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
        
    let startDate = Calendar.current.date(byAdding: .day, value: -7, to: Date())!
        
    let daily = DateComponents(day: 1)
        
    let predicate = HKQuery.predicateForSamples(withStart: startDate, end: Date(), options: .strictStartDate)
        let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [.init(format: "metadata.%K != YES", HKMetadataKeyWasUserEntered), predicate])
        
    let query = HKStatisticsCollectionQuery(quantityType: stepType, quantitySamplePredicate: compoundPredicate, options: .cumulativeSum, anchorDate: startDate, intervalComponents: daily)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search