When I'm launching Health application, I can see the whole distance I've walked or ran for a period of time and see details with separate events. But when I'm trying to get all walking workouts in my application using HealthKit, there are no samples at all.
Does it mean that I can't access workouts that were saved by Apple's Health application or they are not workouts?
Here is my code:
func fetchData() {
guard HKHealthStore.isHealthDataAvailable() else {
throwError(HealthTrackerError.notAvailableOnDevice)
return
}
let type = HKWorkoutType.workoutType()
let completion = { [weak self] (isAuthorized: Bool, error: Error?) in
DispatchQueue.main.async { [weak self] in
isAuthorized ? self?.fetchData(type) : self?.throwError(error)
}
}
switch HKHealthStore().authorizationStatus(for: type) {
case .notDetermined:
HKHealthStore().requestAuthorization(toShare: [type],
read: [type],
completion: completion)
case .sharingAuthorized:
fetchData(type)
case .sharingDenied:
throwError(HealthTrackerError.accessDenied)
}
}
private func fetchData(_ workout: HKWorkoutType) {
let predicate = HKQuery.predicateForWorkouts(with: .walking)
let query = HKSampleQuery(sampleType: workout, predicate: predicate, limit: 0, sortDescriptors: nil) { [weak self] (query, samples, error) in
guard let workouts = samples as? [HKWorkout] else {
self?.throwError(error)
return
}
// No workouts were found
self?.values = workouts
.map { $0.totalEnergyBurned?.doubleValue(for: HKUnit.kilocalorie()) }
.filter { $0 != nil }
.map { $0! }
}
HKHealthStore().execute(query)
}
Thanks to MwcsMac for the link, here is updated code that works for me.
func fetchData() {
guard HKHealthStore.isHealthDataAvailable() else {
throwError(HealthTrackerError.notAvailableOnDevice)
return
}
guard let type = HKQuantityType.quantityType(forIdentifier: .distanceWalkingRunning) else {
throwError(HealthTrackerError.dataTypeNotAvailable)
return
}
let completion = { [weak self] (isAuthorized: Bool, error: Error?) in
DispatchQueue.main.async { [weak self] in
isAuthorized ? self?.fetchData(type) : self?.throwError(error)
}
}
switch HKHealthStore().authorizationStatus(for: type) {
case .notDetermined:
HKHealthStore().requestAuthorization(toShare: [type],
read: [type],
completion: completion)
case .sharingAuthorized:
fetchData(type)
case .sharingDenied:
throwError(HealthTrackerError.accessDenied)
}
}
private func fetchData(_ quantityType: HKQuantityType) {
let predicate = HKQuery.predicateForSamples(withStart: startDate,
end: currentDate,
options: [])
let query = HKSampleQuery(sampleType: quantityType, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: nil) { [weak self] (query, samples, error) in
guard let samples = samples as? [HKQuantitySample] else {
self?.throwError(error)
return
}
self?.values = samples.map { $0.quantity.doubleValue(for: HKUnit.meter()) }
}
HKHealthStore().execute(query)
}