2016-08-25 112 views
1

我今天正在使用以下代碼從healthkit獲取步驟。獲取今天的所有步驟,但從Health kit中使用swift截取手動添加的步驟

func retrieveStepCount(completion: (stepRetrieved: Double) -> Void) { 
     let type = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount) 

    let date = NSDate() 
    let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)! 
    let newDate = cal.startOfDayForDate(NSDate()) 

    let predicate = HKQuery.predicateForSamplesWithStartDate(newDate, endDate: NSDate(), options: .None) // Our search predicate which will fetch all steps taken today 
    let interval: NSDateComponents = NSDateComponents() 
    interval.day = 1 

    let query = HKStatisticsCollectionQuery(quantityType: type!, quantitySamplePredicate: predicate, options: .CumulativeSum, anchorDate: newDate as NSDate, intervalComponents:interval as NSDateComponents) 

    query.initialResultsHandler = { query, results, error in 

     if error != nil { 

      print("Something went Wrong") 
      return 
     } 
     if let myResults = results{ 
      myResults.enumerateStatisticsFromDate(newDate, toDate: NSDate()) { 
       statistics, stop in 
       if let quantity = statistics.sumQuantityForSource(HKSource.defaultSource()) { 

        let steps = quantity.doubleValueForUnit(HKUnit.countUnit()) 

        print("Steps = \(Int(steps))") 
        completion(stepRetrieved: steps) 
       } 
      } 
     } 
    } 
    executeQuery(query) 
} 

現在可以說,我在總

enter image description here

看,我這是由設備自動檢測到了一些措施,這些措施。還有一些是通過其他一些應用程序添加到heathkit。

enter image description here

我希望他們與我m如果他們兩個,但問題是當用戶的一些一些手冊冊步驟來healthkit。

enter image description here

我不想讓這些手動添加步驟。所以基本上我想得到(5,793 - 2300)= 3493步。

我該怎麼做?我試圖獲取HKSource的名稱我知道當用戶手動輸入步驟時,源的名稱是「健康」,但是如何在此基礎上篩選步驟?請指導我這個,我在這裏想念什麼?在此先感謝

回答

2

這可能不是最好的解決方案,但我相信它會工作。你可以做的是獲得使用HKSampleQuery手動添加的所有步驟。這裏是一個例子。

func todayManuallyAddedStepsSteps(completion: (Double, NSError?) ->()) 
    { 

    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] 
      { 
       print("Steps \(result.quantity.doubleValueForUnit(HKUnit.countUnit()))") 
       print() 

       // checking and adding manually added steps 
       if result.sourceRevision.source.name == "Health" { 
        // these are manually added steps 
        print(result.sourceRevision.source.name) 
        print("Steps \(result.quantity.doubleValueForUnit(HKUnit.countUnit()))") 
        steps += result.quantity.doubleValueForUnit(HKUnit.countUnit()) 
       } 
       else{ 
        // these are auto detected steps which we do not want from using HKSampleQuery 
       } 
      } 
      print(steps) 
     } 
     completion(steps, error) 
    } 

    executeQuery(query) 
} 

,然後開始使用HKStatisticsCollectionQuery今天總的步驟如下圖所示

func TodayTotalSteps(completion: (stepRetrieved: Double) -> Void) { 

    let type = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount) // The type of data we are requesting 

    let calendar = NSCalendar.currentCalendar() 
    let interval = NSDateComponents() 
    interval.day = 1 

    let anchorComponents = calendar.components([.Day , .Month , .Year], fromDate: NSDate()) 
    anchorComponents.hour = 0 
    let anchorDate = calendar.dateFromComponents(anchorComponents) 

    let stepsQuery = HKStatisticsCollectionQuery(quantityType: type!, quantitySamplePredicate: nil, options: .CumulativeSum, anchorDate: anchorDate!, intervalComponents: interval) 

    stepsQuery.initialResultsHandler = {query, results, error in 
     let endDate = NSDate() 
     let startDate = calendar.dateByAddingUnit(.Day, value: 0, toDate: endDate, options: []) 
     if let myResults = results{ myResults.enumerateStatisticsFromDate(startDate!, toDate: endDate) { statistics, stop in 
      if let quantity = statistics.sumQuantity(){ 
       let date = statistics.startDate 
       let steps = quantity.doubleValueForUnit(HKUnit.countUnit()) 
       print("\(date): steps = \(steps)") 
       completion(stepRetrieved: steps) 
      } 
      } 
     } 
    } 
    executeQuery(stepsQuery) 
} 

現在你可以調用這些方法和減去像下面

todayManuallyAddedSteps({ (steps , error) in 
      if error != nil{ 
       print(error) 
      } 
      else{ 
       // truncating manuall steps 
       TodayTotalSteps({ (stepRetrieved) in 
        // steps without manuall steps 
        print(Int(stepRetrieved - steps)) 

       }) 
      } 
     }) 
+0

ohh我不知道這一點。謝謝 !! – Byte

1

首先配置HKSources手動添加步驟,這表明我們必須獲取健康數據。 (com.apple.health,com.apple.Health ...)從數據源

func todayTotalSteps() { 

    let completionHandler: (HKStatisticsQuery, HKStatistics?, Error?) -> Void = { 
     (_query, result, error) -> Void in 
     DispatchQueue.main.async { 
      print("Result is \(result)") 

      if let quantity: HKQuantity = result?.sumQuantity() { 

       let steps = quantity.doubleValue(for: HKUnit.count()) 

       print("Steps = \(steps)") 

       self.stepsCount.text = "\(steps)" 
       self.queryGroup?.leave() 
      } 
     } 
    } 

    let stepsCount = HKQuantityType.quantityType(forIdentifier: .stepCount) 
    let predicate = predicateForSamplesToday() 
    self.queryGroup?.enter() 
    let query = HKStatisticsQuery(quantityType: stepsCount!, quantitySamplePredicate: predicate, options: HKStatisticsOptions.cumulativeSum, completionHandler: completionHandler) 

    if (self.healthStore) != nil { 
     self.healthStore.execute(query) 
    }} 

//創建謂詞

private func predicateForSamplesToday() -> NSPredicate 
{ 
    print("Device sources \(self.deviceSources)") 
    let (starDate, endDate): (Date, Date) = self.datesFromToday() 

    var predicate: NSPredicate = HKQuery.predicateForSamples(withStart: starDate, end: endDate, options: HKQueryOptions.strictStartDate) 

    if deviceSources == self.deviceSources { 
     predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate , HKQuery.predicateForObjects(from: deviceSources!)]) 
    } 

    return predicate 
} 
0

func configureSourcePredicate() { 

    self.queryGroup = DispatchGroup() 
    self.deviceSources = Set() 

    //Only get the health data from the apple health without manually added steps 
    let appleHealth = "com.apple.health" 
    self.queryGroup?.enter() 
    let sourcesQueryCompletionHandler : CompletionBlock = { (query , sources , error) in 
     s 
     if let deviceSourcesLocal = sources { 
      for source in deviceSourcesLocal { 
       if source.bundleIdentifier.hasPrefix(appleHealth){ 
        self.deviceSources?.insert(source) 
        print("Device sources are \(source.bundleIdentifier)") 
       } 
      } 
      self.queryGroup?.leave() 
     } 
    } 

    let sampleType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount) 
    let sourceQuery = HKSourceQuery(sampleType: sampleType!, samplePredicate: nil, completionHandler: sourcesQueryCompletionHandler) 
    self.healthStore.execute(sourceQuery) 

    self.queryGroup?.notify(queue: DispatchQueue.global(), execute: { 
     self.todayTotalSteps() 
    }) } 

//步數訪問您應該創建HKSourceQuery謂詞並將其與您想要使用的謂詞組合。在我的情況下,我做了

fileprivate static func configureSourcePredicate(identifier: HKQuantityTypeIdentifier, completion: @escaping(NSPredicate?) -> Void) { 
var deviceSources : Set<HKSource> = Set() 
let appleHealth = "com.apple.health" 
let handler : (HKSourceQuery, Set<HKSource>?, Error?) -> Void = { query , sources , error in 
    if sources == nil || error != nil { 
     completion(nil) 
     return 
    } 
    for source in sources! { 
     if source.bundleIdentifier.hasPrefix(appleHealth){ 
      deviceSources.insert(source) 
     } 
    } 
    completion(HKQuery.predicateForObjects(from: deviceSources)) 
} 
let sampleType = HKQuantityType.quantityType(forIdentifier: identifier) 
let sourceQuery = HKSourceQuery(sampleType: sampleType!, samplePredicate: nil, completionHandler: handler) 
healthStore?.execute(sourceQuery) 
} 

fileprivate static func request(type identifier: HKQuantityTypeIdentifier, startDate : Date, interval : DateComponents, completion : @escaping(TYPE_OF_DATA) -> Void) { 
configureSourcePredicate(identifier: identifier, completion: { sourcePredicate in 
    let type = HKSampleType.quantityType(forIdentifier: identifier) 
    var predicate = HKQuery.predicateForSamples(withStart: startDate, end: Date(), options: [.strictStartDate, .strictEndDate]) 
    if sourcePredicate != nil { 
     predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate , sourcePredicate!]) 
    } 
    let query = HKStatisticsCollectionQuery(quantityType: type!, quantitySamplePredicate: predicate, options: [.cumulativeSum], anchorDate: Date(), intervalComponents: interval) 
    query.initialResultsHandler = { query, results, error in 
     if error != nil || results == nil { 
      return 
     } 
     //your code here 
     DispatchQueue.main.async { 
      completion(RETURNED_DATA) 
     } 
    } 
    healthStore?.execute(query) 
}) 
}