kit healthkit health funciona data como care apple ios swift health-kit

ios - funciona - HealthKit Swift consigue los pasos de hoy



healthkit data types (5)

Esta es la forma correcta de usar HKStatisticsCollectionQuery cortesía de la dirección del código anterior.

Esto está escrito en Swift 3, por lo que es posible que tenga que convertir parte del código a 2.3 o 2 si aún no está en 3.

Swift 3

func retrieveStepCount(completion: (stepRetrieved: Double) -> Void) { // Define the Step Quantity Type let stepsCount = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount) // Get the start of the day let date = Date() let cal = Calendar(identifier: Calendar.Identifier.gregorian) let newDate = cal.startOfDay(for: date) // Set the Predicates & Interval let predicate = HKQuery.predicateForSamples(withStart: newDate, end: Date(), options: .strictStartDate) var interval = DateComponents() interval.day = 1 // Perform the Query let query = HKStatisticsCollectionQuery(quantityType: stepsCount!, quantitySamplePredicate: predicate, options: [.cumulativeSum], anchorDate: newDate as Date, intervalComponents:interval) query.initialResultsHandler = { query, results, error in if error != nil { // Something went Wrong return } if let myResults = results{ myResults.enumerateStatistics(from: self.yesterday, to: self.today) { statistics, stop in if let quantity = statistics.sumQuantity() { let steps = quantity.doubleValue(for: HKUnit.count()) print("Steps = /(steps)") completion(stepRetrieved: steps) } } } } storage.execute(query) }

C objetivo

HKQuantityType *type = [HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]; NSDate *today = [NSDate date]; NSDate *startOfDay = [[NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian] startOfDayForDate:today]; NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:startOfDay endDate:today options:HKQueryOptionStrictStartDate]; NSDateComponents *interval = [[NSDateComponents alloc] init]; interval.day = 1; HKStatisticsCollectionQuery *query = [[HKStatisticsCollectionQuery alloc] initWithQuantityType:type quantitySamplePredicate:predicate options:HKStatisticsOptionCumulativeSum anchorDate:startOfDay intervalComponents:interval]; query.initialResultsHandler = ^(HKStatisticsCollectionQuery * _Nonnull query, HKStatisticsCollection * _Nullable result, NSError * _Nullable error) { if (error != nil) { // TODO } else { [result enumerateStatisticsFromDate:startOfDay toDate:today withBlock:^(HKStatistics * _Nonnull result, BOOL * _Nonnull stop) { HKQuantity *quantity = [result sumQuantity]; double steps = [quantity doubleValueForUnit:[HKUnit countUnit]]; NSLog(@"Steps : %f", steps); }]; } }; [self.storage executeQuery:query];

Estoy creando una aplicación iOS rápida que se integra con el recuento de pasos de un usuario según lo informado por la aplicación Health. Puedo encontrar fácilmente el recuento de pasos del usuario en la última hora, usando esto como mi predicado:

let anHourBeforeNow: NSDate = NSDate().dateByAddingTimeInterval(-60 * 60) let predicate = HKQuery.predicateForSamplesWithStartDate(anHourBeforeNow, endDate: NSDate(), options: .None)

Y tengo el resto hacia abajo, por lo que puedo acceder exitosamente al conteo de pasos del usuario durante la última hora. Pero, ¿cómo puedo acceder a los datos de pasos del usuario desde que comenzó el día, como muestra la aplicación Salud en la sección de pasos?

Estoy tratando de hacer algo como esto:

let date = NSDate() let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)! let newDate = cal.startOfDayForDate(date) let predicate = HKQuery.predicateForSamplesWithStartDate(newDate, endDate: NSDate(), options: .None)

pero este código no se ajusta a la zona horaria (por lo que me da el comienzo del día en UTC, no el comienzo del día en el que se encuentra el usuario) y también recibo conteos de pasos muy inflados (por razones desconocidas).

Entonces, ¿cómo puedo obtener el recuento de pasos del usuario para el día actual, con la misma cantidad de pasos que se informó en Salud, como se muestra aquí:


HKStatisticsCollectionQuery es más adecuado para usar cuando desea recuperar datos durante un período de tiempo. Use HKStatisticsQuery para obtener los pasos para una fecha específica.

Swift 4.2:

let healthStore = HKHealthStore() func getTodaysSteps(completion: @escaping (Double) -> Void) { let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount)! let now = Date() let startOfDay = Calendar.current.startOfDay(for: now) let predicate = HKQuery.predicateForSamples(withStart: startOfDay, end: now, options: .strictStartDate) let query = HKStatisticsQuery(quantityType: stepsQuantityType, quantitySamplePredicate: predicate, options: .cumulativeSum) { _, result, _ in guard let result = result, let sum = result.sumQuantity() else { completion(0.0) return } completion(sum.doubleValue(for: HKUnit.count())) } healthStore.execute(query) }


La consulta que estaba usando toma todos los pasos registrados del usuario de Healthkit, no haciendo el filtro inteligente de los pasos duplicados que hace la aplicación Health. En su lugar, desea obtener los datos de pasos agregados que la aplicación de Salud produce después de combinar pasos de diferentes fuentes para obtener un recuento preciso.

Para hacer eso, puedes usar este código:

func recentSteps2(completion: (Double, NSError?) -> () ) { // this function gives you all of the steps the user has taken since the beginning of the current day. checkAuthorization() // checkAuthorization just makes sure user is allowing us to access their health data. let type = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount) // The type of data we are requesting let date = NSDate() let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)! let newDate = cal.startOfDayForDate(date) let predicate = HKQuery.predicateForSamplesWithStartDate(newDate, endDate: NSDate(), options: .None) // Our search predicate which will fetch all steps taken today // The actual HealthKit Query which will fetch all of the steps and add them up for us. let query = HKSampleQuery(sampleType: type!, predicate: predicate, limit: 0, sortDescriptors: nil) { query, results, error in var steps: Double = 0 if results?.count > 0 { for result in results as! [HKQuantitySample] { steps += result.quantity.doubleValueForUnit(HKUnit.countUnit()) } } completion(steps, error) } storage.executeQuery(query) }


Usando las respuestas anteriores y de Apple aquí: https://developer.apple.com/reference/healthkit/hkstatisticsquery Conseguí lo siguiente para trabajar en swift 2.3 en Xcode 8.0.

class func getStepCountHealth(startDate: NSDate, endDate: NSDate, completion:(Double?, NSError?)->()) { let healthKitStore:HKHealthStore = HKHealthStore() // Define the sample type let sampleType = HKQuantityType.quantityTypeForIdentifier( HKQuantityTypeIdentifierStepCount) // Set the predicate let predicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: endDate, options: .None) // build the query let sampleQuery = HKStatisticsQuery(quantityType: sampleType!, quantitySamplePredicate: predicate, options: .CumulativeSum) { query, results, error in if results != nil { let quantity = results?.sumQuantity() let unit = HKUnit.countUnit() let totalSteps = quantity?.doubleValueForUnit(unit) completion(totalSteps, error) // print("totalSteps for /(endDate) are /(totalSteps!)") } else { completion(nil, error) // print("results are nil") return } } // execute the Query healthKitStore.executeQuery(sampleQuery) }


Para swift 4.2

1) Obtener HealthKitPermission

import HealthKit func getHealthKitPermission() { delay(0.1) { guard HKHealthStore.isHealthDataAvailable() else { return } let stepsCount = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)! self.healthkitStore.requestAuthorization(toShare: [], read: [stepsCount]) { (success, error) in if success { print("Permission accept.") } else { if error != nil { print(error ?? "") } print("Permission denied.") } } } }

2) Para obtener los pasos cuentan para una fecha específica

func getStepsCount(forSpecificDate:Date, completion: @escaping (Double) -> Void) { let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount)! let (start, end) = self.getWholeDate(date: forSpecificDate) let predicate = HKQuery.predicateForSamples(withStart: start, end: end, options: .strictStartDate) let query = HKStatisticsQuery(quantityType: stepsQuantityType, quantitySamplePredicate: predicate, options: .cumulativeSum) { _, result, _ in guard let result = result, let sum = result.sumQuantity() else { completion(0.0) return } completion(sum.doubleValue(for: HKUnit.count())) } self.healthKitStore.execute(query) } func getWholeDate(date : Date) -> (startDate:Date, endDate: Date) { var startDate = date var length = TimeInterval() _ = Calendar.current.dateInterval(of: .day, start: &startDate, interval: &length, for: startDate) let endDate:Date = startDate.addingTimeInterval(length) return (startDate,endDate) }

Cómo utilizar

self.getStepsCount(forSpecificDate: Date()) { (steps) in if steps == 0.0 { print("steps :: /(steps)") } else { DispatchQueue.main.async { print("steps :: /(steps)") } } }