如何在Apple Watch iOS中获得currentStandHour值?

时间:2017-10-16 00:10:37

标签: swift apple-watch

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 

2 个答案:

答案 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)