swiftxcodecounterhealthkitstep

How do I output the stepCount to the Text String (UILabel)


Apologies for my formatting, lack of understanding, terminology etc. I've only been learning for two days so I still don't understand very much. I'm a Graphic Designer by trade and I'm trying to make an app for personal use that calls for some data, and makes it look more visually appealing to me. I want to create a step count for the day and pull this info from the health app.

To begin with, I've gotten to a point where I can call on the HealthKit StepCount to show me steps taken that day. This is successful as long as I use a button (IBAction) to fetch the stepCount data, and then output to the text string (UILabel). (The numbers output with a decimal point 66.0 for example, but one step at a time ha!)

For now, I'd like to simply auto populate the 'totalSteps UILabel' to show the stepCount, rather than have to action it with a button press.

I've tried so many different ways I've lost track of what I've tried and where I've put the attempted code, so any help and/or brief explanation would be great!

Thank You

import UIKit
import HealthKit

class ViewController: UIViewController {

    @IBOutlet weak var totalSteps: UILabel!
    @IBOutlet weak var quotePhrase: UITextView!

    let healthStore = HKHealthStore()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.


        func authoriseHealthKitAccess(_ sender: Any) {
            let healthKitTypes: Set = [
                // access step count
                HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
            ]
            healthStore.requestAuthorization(toShare: healthKitTypes, read: healthKitTypes) { (_, _) in
                print("authrised???")
            }
            healthStore.requestAuthorization(toShare: healthKitTypes, read: healthKitTypes) { (bool, error) in
                if let e = error {
                    print("oops something went wrong during authorisation \(e.localizedDescription)")
                } else {
                    print("User has completed the authorization flow")
                }
            }
        }  
    }

    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, error) in
            var resultCount = 0.0
            guard let result = result else {
                print("Failed to fetch steps rate")
                completion(resultCount)
                return
            }
            if let sum = result.sumQuantity() {
                resultCount = sum.doubleValue(for: HKUnit.count())
            }

            DispatchQueue.main.async {
                completion(resultCount)
            }
        }
        healthStore.execute(query)
    }

    //Button Action Here:

    @IBAction func getTotalSteps(_ sender: Any) {
        getTodaysSteps { (result) in
            print("\(result)")
            DispatchQueue.main.async {
                self.totalSteps.text = "\(result)"
            }
        }
    }
}

Solution

  • You just need to call the same code inside the viewDidLoad. You should also call that code when the user grants the permission to access health data. I covered both scenarios in the below code.

    import UIKit
    import HealthKit
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var totalSteps: UILabel!
        @IBOutlet weak var quotePhrase: UITextView!
    
        let healthStore = HKHealthStore()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.authoriseHealthKitAccess()
        }
    
        func authoriseHealthKitAccess() {
                let healthKitTypes: Set = [
                    // access step count
                    HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
                ]
                healthStore.requestAuthorization(toShare: healthKitTypes, read: healthKitTypes) { [weak self] (bool, error) in
                    if let e = error {
                        print("oops something went wrong during authorisation \(e.localizedDescription)")
                    } else {
                        print("User has completed the authorization flow")
                        self?.updateStepsCountLabel()
                    }
               }
         }
    
        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, error) in
                var resultCount = 0.0
                guard let result = result else {
                    print("Failed to fetch steps rate")
                    completion(resultCount)
                    return
                }
                if let sum = result.sumQuantity() {
                    resultCount = sum.doubleValue(for: HKUnit.count())
                }
    
                DispatchQueue.main.async {
                    completion(resultCount)
                }
            }
            healthStore.execute(query)
        }
    
        private func updateStepsCountLabel() {
            getTodaysSteps { (result) in
                print("\(result)")
                DispatchQueue.main.async {
                    self.totalSteps.text = "\(result)"
                }
            }
        }
    
        //Button Action Here:
    
        @IBAction func getTotalSteps(_ sender: Any) {
            updateStepsCountLabel()
        }
    }