从 HealthKit 获取昨天的步数
Getting yesterdays steps from HealthKit
我正在构建一个供个人使用的应用程序,目前我正在研究如何从 healthkit 中准确获取昨天的步数。然后从那里,将它放入一个变量中(应该很容易,我知道)。
我有一个 HealthKitManager class 从视图内部调用函数,然后将其附加到同一视图中的变量。
我已经搜索了大部分的 healthKit 问题,并且得到了数据,但我认为它不是准确的数据。我昨天的 phone 数据是 1442 步,但它返回了 2665 步。最重要的是,当我尝试将数据放入变量时,它打印为 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.
}
}
来自
的输出
print(Player.User.Gold.getSteps(), "IN PLAYER")
是
0 IN PLAYER
来自
的输出
print("\(steps) STEPS FROM HEALTH KIT")
是
2665.0 STEPS FROM HEALTH KIT
所以,基本上我的问题是:
- 整个昨天我需要什么 NSDate()?
- 如何从 yesterdaySteps() 中获取步骤并将它们正确地放入 UpdateViewController 中的变量中?
感谢您的帮助!
这是我在 healthStore 中使用的方法 class
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)
}
下面是我的使用方法
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)
})
}
})
}
这里是上面用于手动添加的步骤的函数,我们正在截断这些步骤以获得准确的步骤
func todayManuallyAddedSteps(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]
{
// checking and adding manually added steps
if result.sourceRevision.source.name == "Health" {
// these are manually added steps
steps += result.quantity.doubleValueForUnit(HKUnit.countUnit())
}
else{
// these are auto detected steps which we do not want from using HKSampleQuery
}
}
completion(steps, error)
} else {
completion(steps, error)
}
}
executeQuery(query)
}
希望对您有所帮助。如果您遇到任何问题,请告诉我。
您可以使用HKStatisticsQuery
let quantityType = HKSampleType.quantityType(forIdentifier: .stepCount)!
let predicate = HKQuery.predicateForSamples(
withStart: startDate,
end: endDate,
options: [.strictStartDate, .strictEndDate]
)
let query = HKStatisticsQuery(
quantityType: quantityType,
quantitySamplePredicate: predicate,
options: .cumulativeSum) { (query, result, error) in
guard let result = result, error == nil else {
print("HeathService error \(String(describing: error))")
return
}
callback(result)
}
我正在构建一个供个人使用的应用程序,目前我正在研究如何从 healthkit 中准确获取昨天的步数。然后从那里,将它放入一个变量中(应该很容易,我知道)。
我有一个 HealthKitManager class 从视图内部调用函数,然后将其附加到同一视图中的变量。
我已经搜索了大部分的 healthKit 问题,并且得到了数据,但我认为它不是准确的数据。我昨天的 phone 数据是 1442 步,但它返回了 2665 步。最重要的是,当我尝试将数据放入变量时,它打印为 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.
}
}
来自
的输出print(Player.User.Gold.getSteps(), "IN PLAYER")
是
0 IN PLAYER
来自
的输出print("\(steps) STEPS FROM HEALTH KIT")
是
2665.0 STEPS FROM HEALTH KIT
所以,基本上我的问题是:
- 整个昨天我需要什么 NSDate()?
- 如何从 yesterdaySteps() 中获取步骤并将它们正确地放入 UpdateViewController 中的变量中?
感谢您的帮助!
这是我在 healthStore 中使用的方法 class
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)
}
下面是我的使用方法
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)
})
}
})
}
这里是上面用于手动添加的步骤的函数,我们正在截断这些步骤以获得准确的步骤
func todayManuallyAddedSteps(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]
{
// checking and adding manually added steps
if result.sourceRevision.source.name == "Health" {
// these are manually added steps
steps += result.quantity.doubleValueForUnit(HKUnit.countUnit())
}
else{
// these are auto detected steps which we do not want from using HKSampleQuery
}
}
completion(steps, error)
} else {
completion(steps, error)
}
}
executeQuery(query)
}
希望对您有所帮助。如果您遇到任何问题,请告诉我。
您可以使用HKStatisticsQuery
let quantityType = HKSampleType.quantityType(forIdentifier: .stepCount)!
let predicate = HKQuery.predicateForSamples(
withStart: startDate,
end: endDate,
options: [.strictStartDate, .strictEndDate]
)
let query = HKStatisticsQuery(
quantityType: quantityType,
quantitySamplePredicate: predicate,
options: .cumulativeSum) { (query, result, error) in
guard let result = result, error == nil else {
print("HeathService error \(String(describing: error))")
return
}
callback(result)
}