当之前在设备上授权 healthkit 访问时工作正常,但否则会崩溃

Works fine when healthkit access was previously authorized on device but crashes otherwise

override func viewDidLoad() {
    super.viewDidLoad()
    ref = Database.database().reference()
    let healthKitTypes: Set = [
        // access step count
        HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
    ]
    healthStore.requestAuthorization(toShare: healthKitTypes, read: healthKitTypes) { (_, _) in
        print("authorized???")
    }
    healthStore.requestAuthorization(toShare: healthKitTypes, read: healthKitTypes) { (bool, error) in
        if let e = error {
            print("oops something went wrong during authorization \(e.localizedDescription)")
        } else {
            print("User has completed the authorization flow")
        }
    }


    getTodaysSteps { (result) in
        print("\(result)")
        self.steps = result

        DispatchQueue.main.async {
            if result == 0 {
                self.StepDisplay.text = " You haven't walked"
            } else {
                self.StepDisplay.text = "\(result)"
            }

        }
    }


    getStepHistory()



}


func getStepHistory() {
    let calendar = Calendar.current
    var interval = DateComponents()
    interval.day = 1

    // Set the anchor date to Monday at 3:00 a.m.
    var anchorComponents = calendar.dateComponents([.day, .month, .year, .weekday], from: Date())


    let offset = (7 + (anchorComponents.weekday ?? 0) - 2) % 7
    anchorComponents.day = (anchorComponents.day ?? 0) - offset
    anchorComponents.hour = 0
    anchorComponents.minute = 1

    guard let anchorDate = calendar.date(from:anchorComponents) else {
        fatalError("*** unable to create a valid date from the given components ***")
    }

    guard let quantityType = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount) else {
        fatalError("*** Unable to create a step count type ***")
    }

当授权已在设备上提供时,此代码可以正常工作。但是,如果之前未授权,除非在 viewDidLoad 中将 getStepHistory() 注释掉,否则它将无法工作。我尝试从 getStepHistory() 函数中请求额外的授权,但它没有解决问题

如果已经授权,需要在完成块中调用getStepHistoryrequestAuthorization

healthStore.requestAuthorization(toShare: healthKitTypes, read: healthKitTypes) { (success, error) in
    if let e = error {
        print("oops something went wrong during authorization \(e.localizedDescription)")
    } else if success {
        print("User has granted access")
        getStepHistory()
    } else {
        print("User has completed the authorization flow but there is no access")
    }
}

请求用户许可

要请求授权,我们调用

requestAuthorization(toShare:,readTypes:,completion:) on the HKHealthStore instance. This method accepts three parameters:

  • 一组可选的 HKSampleType 对象
  • 一组可选的 HKObjectType 对象
  • 一个带有两个参数的完成处理程序,一个指示授权请求结果(成功或不成功)的布尔值和一个可选的错误

重要的是要了解完成处理程序的布尔值并不表示用户是授予还是拒绝访问所请求的健康数据类型。它只通知应用程序用户是否响应了应用程序的授权请求。如果用户通过取消授权请求关闭表单,则完成处理程序的布尔值设置为 false。

在您看来已加载:

healthStore.requestAuthorization(toShare: healthKitTypes, read: healthKitTypes) { (success, error) in
    if let err = error {
        print("Error \(err.localizedDescription)")
    } else if success {
        // Get the Step Count....
        getStepHistory()
    } else {
        print("No access to healthkit data")
    }
}

可选你可以试试这个函数来获取步数:

    let healthStore = HKHealthStore()

    func getTodaysSteps(completion: @escaping (Double) -> Void) {
        let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount)!

        let now = Date()
        let startOfDay = Calendar.current.startOfDay(for: now)
        let predicate = HKQuery.predicateForSamples(withStart: startOfDay, end: now, options: .strictStartDate)

        let query = HKStatisticsQuery(quantityType: stepsQuantityType, quantitySamplePredicate: predicate, options: .cumulativeSum) { _, result, _ in
            guard let result = result, let sum = result.sumQuantity() else {
                completion(0.0)
                return
            }
            completion(sum.doubleValue(for: HKUnit.count()))
        }

        healthStore.execute(query)
    }