https://developer.apple.com/documentation/healthkit/hkcategorytypeidentifier/1615539-applestandhour
我想检索指示用户是否在这个时间站立的值。
我还希望能够检索当天的StandHours计数。
以下是我一直试图理解的苹果链接,以便从healthKit获取价值。我提供这些链接,以帮助提供对我所寻找内容的理解,并帮助您回答我的问题。
https://developer.apple.com/documentation/healthkit/hkcategorytypeidentifier/1615539-applestandhour
健康套件类别类型标识符
https://developer.apple.com/documentation/healthkit/hkcategorytypeidentifier
健康套件常量
https://developer.apple.com/documentation/healthkit/healthkit_constants
健康套件
https://developer.apple.com/documentation/healthkit
布鲁诺的回答只是答案的一半。例如。他的" sandunit"变量是他如何拉动用户今天的小时数。我测试了它。我也纠正了他的代码中的拼写错误。 :)。此外,我假设它必须从摘要var的范围内拉出。
我在stackOverflow上发现了另一个可能提供一些线索的问题。我认为他们设法通过HKCategoryTypeIdentifier提取值。 Watch os 2.0 beta: access heart beat rate
这是我尝试过的代码,据我所知:
import UIKit
import HealthKit
import HealthKitUI
class ViewController: UIViewController {
let hkStoreOnVC : HKHealthStore = HKHealthStore()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
authorizeHealthKit()
hkTest()
hkTest2()
}
func authorizeHealthKit() { //-> Bool {
print("health kit authorize?")
let healthStore = HKHealthStore()
let objectTypes: Set<HKObjectType> = [
HKObjectType.activitySummaryType()
]
healthStore.requestAuthorization(toShare: nil, read: objectTypes) { (success, error) in
// Authorization request finished, hopefully the user allowed access!
print("health kit authorized")
}
}
func hkTest() {
print("health kit test.")
let calendar = Calendar.autoupdatingCurrent
var dateComponents = calendar.dateComponents(
[ .year, .month, .day ],
from: Date()
)
// This line is required to make the whole thing work
dateComponents.calendar = calendar
let predicate = HKQuery.predicateForActivitySummary(with: dateComponents)
//----------------------
let query = HKActivitySummaryQuery(predicate: predicate) { (query, summaries, error) in
print("query")
guard let summaries = summaries, summaries.count > 0
else {
print("no summaries")
return
}
// Handle data
for thisSummary in summaries {
// print("for each summary")
let standUnit = HKUnit.count()
let standHours = thisSummary.appleStandHours.doubleValue(for: standUnit)
print("stand hours \(standHours)")
}//end for
}//end query
//----------------------
//----------------------
}
func hkTest2() {
var isEnabled = true
print ("authorize health kit" )
if HKHealthStore.isHealthDataAvailable() {
let stepsCount = NSSet(objects: HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount ) )
for thisValue in stepsCount {
// thisValue.
print("thisValue: \(thisValue)")
}
print(" authorize HK - steps count \(stepsCount) ")
}
// Create the date components for the predicate
guard let calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian) else {
fatalError("*** This should never fail. ***")
}
let endDate = NSDate()
guard let startDate = calendar.date(byAdding: .day, value: -7, to: endDate as Date, options: []) else {
fatalError("*** unable to calculate the start date ***")
}
let units: NSCalendar.Unit = [.day, .month, .year, .era]
var startDateComponents = calendar.components(units, from: startDate)
startDateComponents.calendar = calendar as Calendar
var endDateComponents = calendar.components(units, from: endDate as Date)
endDateComponents.calendar = calendar as Calendar
// Create the predicate for the query
let summariesWithinRange = HKQuery.predicate(forActivitySummariesBetweenStart: startDateComponents, end: endDateComponents)
// Build the query
let query = HKActivitySummaryQuery(predicate: summariesWithinRange) { (query, summaries, error) -> Void in
guard let activitySummaries = summaries else {
guard let queryError = error else {
fatalError("*** Did not return a valid error object. ***")
}
// Handle the error here...
return
}
for thisSummary in activitySummaries {
// print("for each summary")
let standUnit = HKUnit.count()
let standHours = thisSummary.appleStandHours.doubleValue(for: standUnit)
// let stoodThisHourMaybe = thisSummary.appleStandHours.categ //doubleValue(for: standUnit)
//\(thisSummary.description) //stand unit _\(standUnit)_
print("day#\(thisSummary.dateComponents(for: calendar as Calendar).day) stand hours \(standHours) ")
}//end for
// // Do something with the summaries here...
for thisItem in activitySummaries {
//thisItem.appleStandHours
print("abc \( thisItem.appleStandHours ) " )
}//end for
}
// Run the query
let hkStore : HKHealthStore = HKHealthStore()
hkStore.execute(query)
//***
let aStandHour = HKCategoryType.categoryType(forIdentifier: .appleStandHour)
// This is the type you want updates on. It can be any health kit type, including heart rate.
// let distanceType = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.distanceWalkingRunning)
// Match samples with a start date after the workout start
// let predicate = .predicat //( , endDate: nil, options: .None)
// let theDate : Date =
let thepredicate = HKQuery.predicateForCategorySamples(with: .greaterThanOrEqualTo, value: 0) //.predicateForSamplesWithStartDate(startDate , endDate: nil, options: .None)
// predicate
// let predicate = . //(theDate , endDate: nil, options: .None)
let hka : HKQueryAnchor = HKQueryAnchor(fromValue: 0)
let sHourQuery = HKAnchoredObjectQuery(type: aStandHour!, predicate: thepredicate, anchor: hka, limit: 0, resultsHandler: { ( query, samples, deletedObjects, anchor, error) -> Void in
// Handle when the query first returns results
// TODO: do whatever you want with samples (note you are not on the main thread)
print("getting here A?")
// for thisSample in samples! {
// print("A smpLType \(thisSample.sampleType) thisSample \(thisSample)")
// }
})
// This is called each time a new value is entered into HealthKit (samples may be batched together for efficiency)
sHourQuery.updateHandler = { (query, samples, deletedObjects, anchor, error) -> Void in
// Handle update notifications after the query has initially run
// TODO: do whatever you want with samples (note you are not on the main thread)
print("getting here B?")
for thisSample in samples! {
print("B smpLType \(thisSample.sampleType) thisSample \(thisSample)")
}
}
// Start the query
self.hkStoreOnVC.execute(sHourQuery)
//***
}//end func
func myCompletionHandler(bTest: Bool ) {
print("my completion handler")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}//end viewController Class
这里是代码输出 - 日志永远不会打印到&#34;到达这里b?&#34;:
health kit authorize?
health kit test.
authorize health kit
health kit authorized
thisValue: HKQuantityTypeIdentifierStepCount
authorize HK - steps count {(
HKQuantityTypeIdentifierStepCount
)}
2017-11-04 19:18:30.100562-0500 watchapptest[25048:4695625] refreshPreferences: HangTracerEnabled: 0
2017-11-04 19:18:30.100600-0500 watchapptest[25048:4695625] refreshPreferences: HangTracerDuration: 500
2017-11-04 19:18:30.100615-0500 watchapptest[25048:4695625] refreshPreferences: ActivationLoggingEnabled: 0 ActivationLoggingTaskedOffByDA:0
getting here A?
day#Optional(28) stand hours 14.0
day#Optional(29) stand hours 14.0
day#Optional(30) stand hours 14.0
day#Optional(31) stand hours 14.0
day#Optional(1) stand hours 16.0
day#Optional(2) stand hours 13.0
day#Optional(3) stand hours 15.0
day#Optional(4) stand hours 13.0
abc 14 count
abc 14 count
abc 14 count
abc 14 count
abc 16 count
abc 13 count
abc 15 count
abc 13 count
答案 0 :(得分:3)
我是HealthKit的新手,所以也许有更好的方法可以做到这一点。但这似乎对我有用。我查看了实际的站立时间,并使用minutes > 0
致电完成处理程序。
private let store = HKHealthStore()
func askPermission() {
let standType = HKQuantityType.quantityType(forIdentifier: .appleStandTime)!
store.requestAuthorization(toShare: [], read: [standType], completion: { (success, error) in
self.didStandThisHour { (didStand) in
print("Did stand this hour: \(didStand)")
}
})
}
func didStandThisHour(_ didStand: @escaping (Bool) -> ()) {
let store = HKHealthStore()
let calendar = Calendar.autoupdatingCurrent
let dateComponents = calendar.dateComponents([.year, .month, .day, .hour], from: Date())
let endDate = Date()
let startDate = calendar.date(from: dateComponents)!
let standTime = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.appleStandTime)!
var interval = DateComponents()
interval.hour = 1
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: .strictStartDate)
let query = HKStatisticsCollectionQuery(quantityType: standTime, quantitySamplePredicate: predicate, options: [.cumulativeSum], anchorDate: startDate, intervalComponents:interval)
query.initialResultsHandler = { query, results, error in
guard error == nil, let myResults = results else {
fatalError("Something is wrong with HealthKit link")
}
myResults.enumerateStatistics(from: startDate, to: endDate, with: { (statistics, stop) in
guard let quantity = statistics.sumQuantity() else {
didStand(false)
return
}
let minutes = quantity.doubleValue(for: .minute())
didStand(minutes > 0)
})
}
store.execute(query)
}
答案 1 :(得分:2)
好的,如果您想要检索今天的活动响铃信息(包括停留时间),您首先请求您要检索的对象类型的用户授权:
let healthStore = HKHealthStore()
let objectTypes: Set<HKObjectType> = [
HKObjectType.activitySummaryType()
]
healthStore.requestAuthorization(toShare: nil, read: objectTypes) { (success, error) in
// Authorization request finished, hopefully the user allowed access!
}
然后您可以使用此谓词来检索今天的日期:
let calendar = Calendar.autoupdatingCurrent
var dateComponents = calendar.dateComponents(
[ .year, .month, .day ],
from: Date()
)
// This line is required to make the whole thing work
dateComponents.calendar = calendar
let predicate = HKQuery.predicateForActivitySummary(with: dateComponents)
创建查询...
let query = HKActivitySummaryQuery(predicate: predicate) { (query, summaries, error) in
guard let summaries = summaries, summaries.count > 0
else {
return
}
// Handle data
}
您收到的数据类型为HKActivitySummary,您可以检索,例如:
let sandUnit = HKUnit.count()
let standHours = summary.appleStandHours.doubleValue(for: standUnit)