I'm making Health App. I want to get walkingRunningDistance
from HealthKit
in Swift. But, I have a problem. Return value is 0.0mile.
Why return value is 0 mile?
My code is this.
func recentSteps3(completion: (Double, NSError?) -> () ){
let type = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning)
let date = NSDate()
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let newDate = cal.startOfDayForDate(date)
let predicate = HKQuery.predicateForSamplesWithStartDate(newDate, endDate: NSDate(), options: HKQueryOptions.StrictStartDate)
let query = HKSampleQuery(sampleType: type!, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: nil) { query, results, error in
var distance: Double = 0
if results?.count > 0
{
for result in results as! [HKQuantitySample]
{
distance += result.quantity.doubleValueForUnit(HKUnit.mileUnit())
}
}
completion(distance, error)
}
healthAuth.healthStore.executeQuery(query)
}
Your code will return a value if
- You have requested permission from the user to read distanceWalkingRunning from HealthKit
- The user has granted your app permission.
If not, your code will return 0.
To request authorization, you can call
func requestAuthorization(toShare typesToShare: Set<HKSampleType>?, read typesToRead: Set<HKObjectType>?, completion: @escaping (Bool, Error?) -> Swift.Void)
where typesToRead
contains
let distanceType = HKSampleType.quantityType(forIdentifier: HKQuantityTypeIdentifier.distanceWalkingRunning)!
I believe that using a HKStatisticsQuery or HKStatisticsCollectionQuery will be more efficient. Here is an example.
guard let type = HKSampleType.quantityType(forIdentifier: .distanceWalkingRunning) else {
fatalError("Something went wrong retriebing quantity type distanceWalkingRunning")
}
let date = Date()
let cal = Calendar(identifier: Calendar.Identifier.gregorian)
let newDate = cal.startOfDay(for: date)
let predicate = HKQuery.predicateForSamples(withStart: newDate, end: Date(), options: .strictStartDate)
let query = HKStatisticsQuery(quantityType: type, quantitySamplePredicate: predicate, options: [.cumulativeSum]) { (query, statistics, error) in
var value: Double = 0
if error != nil {
print("something went wrong")
} else if let quantity = statistics?.sumQuantity() {
value = quantity.doubleValue(for: HKUnit.mile())
}
DispatchQueue.main.async {
completion(value)
}
}
healthStore.execute(query)
After enabled the HealthKit in your project's capabilities and added the necessary "Privacy - Health Share Usage Description" key to your info.plist file...
Ensure you are requesting for the approval of the user by adding this to the ViewController.swift, practically in the viewDidLoad() function.
let store = HKHealthStore()
let stepType = HKQuantityType.quantityType(forIdentifier: .stepCount)!
let woType = HKObjectType.workoutType()
store.requestAuthorization(toShare: [], read: [stepType, woType], completion: { (isSuccess, error) in
if isSuccess {
print("Working")
self.getSteps()
} else {
print("Not working")
}
})
Then create the getSteps() function.
func getSteps() {
let startDate = Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: Date())!
let endDate = Date()
print("Collecting workouts between \(startDate) and \(endDate)")
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: HKQueryOptions.strictEndDate)
let query = HKSampleQuery(sampleType: HKQuantityType.quantityType(forIdentifier: .distanceWalkingRunning)!, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: nil) { (query, results, error) in
for item in results! {
print(item)
}
}
store.execute(query)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With