2016-09-23 4 views
4

Ich baue eine App für den persönlichen Gebrauch, und ich bin derzeit fest, wie man gestern Schritte aus dem Healthkit genau zu bekommen. Und dann von dort, es in eine Variable zu platzieren (sollte einfach sein, ich weiß).Getting Yesterdays Schritte von HealthKit

Ich habe eine HealthKitManager-Klasse, die die Funktion innerhalb einer Ansicht aufruft und diese dann an eine Variable aus derselben Ansicht anfügt.

Ich habe die meisten HealthKit Fragen durchforstet, und ich bekomme Daten zurück, aber ich denke nicht, dass es genaue Daten sind. Meine Telefondaten von gestern sind 1442 Schritte, aber es gibt 2665 Schritte zurück. Hinzu kommt, dass, wenn ich versuche, um die Daten zu setzen ist eine Variable, es druckt als 0

HealthKitManagerClass

import Foundation 
import HealthKit 

class HealthKitManager { 
let storage = HKHealthStore() 

init() 
{ 
    checkAuthorization() 
} 

func checkAuthorization() -> Bool 
{ 
    // Default to assuming that we're authorized 
    var isEnabled = true 

    // Do we have access to HealthKit on this device? 
    if HKHealthStore.isHealthDataAvailable() 
    { 
     // We have to request each data type explicitly 
     let steps = NSSet(object: HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount)!) 

     // Now we can request authorization for step count data 
     storage.requestAuthorizationToShareTypes(nil, readTypes: steps as? Set<HKObjectType>) { (success, error) -> Void in 
      isEnabled = success 
     } 
    } 
    else 
    { 
     isEnabled = false 
    } 

    return isEnabled 
} 

func yesterdaySteps(completion: (Double, NSError?) ->()) 
{ 
    // The type of data we are requesting (this is redundant and could probably be an enumeration 
    let type = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount) 

    // Our search predicate which will fetch data from now until a day ago 
    // (Note, 1.day comes from an extension 
    // You'll want to change that to your own NSDate 

    let calendar = NSCalendar.currentCalendar() 
    let yesterday = calendar.dateByAddingUnit(.Day, value: -1, toDate: NSDate(), options: []) 

    //this is probably why my data is wrong 
    let predicate = HKQuery.predicateForSamplesWithStartDate(yesterday, endDate: NSDate(), options: .None) 

    // The actual HealthKit Query which will fetch all of the steps and sub 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()) 
      } 
     } 

     //I'm unsure if this is correct as well 
     completion(steps, error) 
     print("\(steps) STEPS FROM HEALTH KIT") 
     //this adds the steps to my character (is this in the right place) 
     Player.User.Gold.addSteps(Int(steps)) 
    } 
    //not 100% on what this does, but I know it is necessary 
    storage.executeQuery(query) 
}} 

ViewControllerClass

import UIKit 
import Foundation 

class UpdateViewController: UIViewController { 

@IBOutlet var back: UIButton! 

let HKM = HealthKitManager() 
var stepsFromPhone = Double() 


override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 

    back.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2)) 


    HKM.yesterdaySteps(){ steps, error in 
     self.stepsFromPhone = steps 
    } 

    Player.User.Gold.addSteps(Int(stepsFromPhone)) 
    print(Player.User.Gold.getSteps(), "IN PLAYER") 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 


} 

Die Ausgabe von

print(Player.User.Gold.getSteps(), "IN PLAYER") 

0 IN PLAYER 

wird die Ausgabe von

print("\(steps) STEPS FROM HEALTH KIT") 

ist

2665.0 STEPS FROM HEALTH KIT 

so, im Grunde meine Fragen sind:

  1. was NSDate() kann ich für die ganze brauchen von gestern?
  2. Wie nehme ich die Schritte von grew.seps() und ordne sie korrekt in eine Variable im UpdateViewController?

Vielen Dank für jede Hilfe!

+0

Haben Sie einen Drittanbieter-Tracker mit Ihrem Telefon verbunden? –

+0

Was ist Ihre aktuelle Anforderung? Ein Beispiel, wenn ein Benutzer manuell Schritte zu Healthkit hinzufügt, möchten Sie dann auch lesen oder nicht? –

+0

Es gibt keine Drittanbieter-Tracker mit meinem Telefon, und die Anforderung besteht nur darin, die Schritte aus der Telefon-Gesundheits-App zu lesen. Brauchen Sie keine manuelle Schritte hinzufügen, entweder – mint

Antwort

6

Dies ist die Methode, die ich in meiner healthStore-Klasse am

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() 

     var steps = 0.0 
     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 
       steps = quantity.doubleValueForUnit(HKUnit.countUnit()) 
       // print("\(date): steps = \(steps)") 
      } 

      completion(stepRetrieved: steps) 
      } 
     } else { 

      completion(stepRetrieved: steps) 
     } 
    } 
    executeQuery(stepsQuery) 
} 

und hier ist, wie ich es

func getStepsData() { 

    // I am sendng steps to my server thats why using this variable 
    var stepsToSend = 0 

     MyHealthStore.sharedHealthStore.todayManuallyAddedSteps({ (steps , error) in 
      if error != nil{ 
       // handle error 
      } 
      else{ 
       // truncating manuall steps 
       MyHealthStore.sharedHealthStore.TodayTotalSteps({ (stepRetrieved) in 
        stepsToSend = Int(stepRetrieved - steps) 
       }) 
      } 
     }) 
} 

bin mit und hier ist die oben für die manuell hinzugefügt Schritte Funktion, die wir sind abgeschnitten, um genaue Schritte zu erhalten

Ich hoffe, es hilft. Lassen Sie mich wissen, wenn Sie irgendein Problem haben.

+0

funktioniert perfekt! Nur eine Warnung an andere, die möglicherweise das gleiche Problem haben: Wenn Sie nach der Funktion, in der Sie Daten erhalten, Labels mit den zu aktualisierenden Variablen verbunden haben, werden sie möglicherweise aktualisiert, bevor die Abfrage beendet wird . Das Hinzufügen eines NSTimers, der die Etiketten nach 2 Sekunden aktualisiert hat, hat für mich funktioniert – mint

Verwandte Themen