简体   繁体   English

使用 HealthKit 结果填充 TableView - Swift

[英]Populate TableView with HealthKit Results - Swift

I'm trying to populate my table view with the return of my HealthKit from Apple Health.我正在尝试通过从 Apple Health 返回我的 HealthKit 来填充我的表格视图。 I currently get the date and heart rate from Apple Health from the past 7 days.我目前从 Apple Health 获取过去 7 天的日期和心率。 I can see everything clearly in my console.我可以在控制台中清楚地看到所有内容。

Here's my block code:这是我的块代码:

    func getTodaysHeartRate(completion: (@escaping (HKQuantitySample) -> Void)) {
            print("func")
            let heartRateUnit:HKUnit = HKUnit(from: "count/min")
            let heartRateType:HKQuantityType = HKQuantityType.quantityType(forIdentifier: .heartRate)!


            let startDate = Date() - 7 * 24 * 60 * 60
            let endDate = Date()
            let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: [])


            let sortDescriptors = [
                NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)
            ]

            let heartRateQuery = HKSampleQuery(sampleType: heartRateType,
                                               predicate: predicate,
                                               limit: Int(HKObjectQueryNoLimit),
                                               sortDescriptors: sortDescriptors)
            { (query:HKSampleQuery, results:[HKSample]?, error:Error?) -> Void in

                guard error == nil else { print("error"); return }
                //print("results")
                //print(results!)

                for result in results! {
                    guard let currData:HKQuantitySample = result as? HKQuantitySample else { return }

                    print("Heart Rate: \(currData.quantity.doubleValue(for: heartRateUnit))")
                    print("Times: \(currData.startDate)")
                    //print("End Date: \(currData.endDate)")
                    //print("quantityType: \(currData.quantityType)")
                    //print("Metadata: \(String(describing: currData.metadata))")
                    //print("UUID: \(currData.uuid)")
                    //print("Source: \(currData.sourceRevision)")
                    //print("Device: \(String(describing: currData.device))")
                    //print("---------------------------------\n")
                }

            }
            healthStore.execute(heartRateQuery)

        }

    @IBOutlet weak var heartRate: UILabel!
    @IBAction func getHeartRate(_ sender: Any) {
        getTodaysHeartRate { (result) in
            print("\(result)")
            DispatchQueue.main.async {
                self.heartRate.text = "\(result)"
            }
    }

}
    @IBAction func emailResult(_ sender: Any) {
        self.sendEmail()
    }

Here I have created as sample project for you where I made some changes with your code which is shown below and comments are added for that:在这里,我为您创建了示例项目,其中我对您的代码进行了一些更改,如下所示,并为此添加了注释:

import UIKit
import HealthKit

class ViewController: UIViewController {

    //add a tableview to your storyboard and connect delegate and datasource
    @IBOutlet weak var tblHeartRateData: UITableView!

    let healthStore = HKHealthStore()

    //create an array of HKSample which will hold your data from healthkit or you can create a custom class for that
    var heartRateData: [HKSample]?

    override func viewDidLoad() {
        super.viewDidLoad()

        //Get data access permission
        getHealthKitPermission()
    }

    @IBAction func getHeartRate(_ sender: Any) {

        getTodaysHeartRate { (result) in
            DispatchQueue.main.async {

                //Here you will get your healthkit data.
                self.heartRateData = result
                //Once you get it reload your table view
                self.tblHeartRateData.reloadData()
            }
        }
    }

    //Permission
    func getHealthKitPermission() {
        let healthkitTypesToRead = NSSet(array: [
            HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate) ?? ""
            ])

        healthStore.requestAuthorization(toShare: nil, read: healthkitTypesToRead as? Set) { (success, error) in
            if success {
                print("Permission accept.")

            } else {
                if error != nil {
                    print(error ?? "")
                }
                print("Permission denied.")
            }
        }
    }

    func getTodaysHeartRate(completion: (@escaping ([HKSample]) -> Void)) {
        print("func")

        let heartRateType:HKQuantityType = HKQuantityType.quantityType(forIdentifier: .heartRate)!

        //predicate
        let startDate = Date() - 2 * 24 * 60 * 60
        let endDate = Date()
        let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: [])

        //descriptor
        let sortDescriptors = [
            NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)
        ]

        let heartRateQuery = HKSampleQuery(sampleType: heartRateType,
                                           predicate: predicate,
                                           limit: Int(HKObjectQueryNoLimit),
                                           sortDescriptors: sortDescriptors)
        { (query:HKSampleQuery, results:[HKSample]?, error:Error?) -> Void in

            guard error == nil else { print("error"); return }

            //Here I have added completion which will pass data when button will tap.
            completion(results!)

        }
        healthStore.execute(heartRateQuery)

    }
}

//TableView Methods.
extension ViewController: UITableViewDataSource, UITableViewDelegate {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return heartRateData?.count ?? 0
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! HeartDataTableViewCell

        let heartRateUnit:HKUnit = HKUnit(from: "count/min")
        let heartData = self.heartRateData?[indexPath.row]
        guard let currData:HKQuantitySample = heartData as? HKQuantitySample else { return UITableViewCell()}

        cell.lblHeartRate.text = "Heart Rate: \(currData.quantity.doubleValue(for: heartRateUnit))"

        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 106
    }
}

for more info check our THIS demo project.有关更多信息,请查看我们的这个演示项目。

And your result will be:你的结果将是:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM