I'm trying to create a widget for myself so I can see my measurements on the screen.
I successfully get Body Mass and Body Mass Index data from HealthKit, but my code doesn't work for fetching the Body Fat Percentage data.
Couldn't find anything about Body Fat Percentage on my search, so I wanted to ask if I need to use a different way to fetch its data?
Function for fetching the data:
class func getMostRecentSample(for sampleType: HKSampleType,
completion: @escaping (HKQuantitySample?, Error?) -> Swift.Void) {
let mostRecentPredicate = HKQuery.predicateForSamples(withStart: Date.distantPast,
end: Date(),
options: .strictEndDate)
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate,
ascending: false)
let limit = 1
// This step won't execute as usual while working for Body Fat Percentage data;
let sampleQuery = HKSampleQuery(sampleType: sampleType,
predicate: mostRecentPredicate,
limit: limit,
sortDescriptors: [sortDescriptor]) { (query, samples, error) in
DispatchQueue.main.async {
guard let samples = samples,
let mostRecentSample = samples.first as? HKQuantitySample else {
completion(nil, error)
return
}
completion(mostRecentSample, nil)
}
}
HKHealthStore().execute(sampleQuery) // then jumps to here.
}
Function for getting the string from the fetched data:
class func getSamples(for sampleType: HKSampleType,
unit: HKUnit,
completion: @escaping (String?, Error?) -> Swift.Void) {
getMostRecentSample(for: sampleType) {(sample, error) in
guard let sample = sample else {
return
}
let BMI = String(sample.quantity.doubleValue(for: unit))
// let weight = String(sample.quantity.doubleValue(for: unit))
// let fatPercentage = String(sample.quantity.doubleValue(for: unit))
completion(BMI, nil)
}
}
Sending the data to Timeline then preview it:
func getTimeline(in context: Context, completion: @escaping (Timeline<WeightEntry>) -> Void) {
let currentDate = Date()
let refreshDate = Calendar.current.date(byAdding: .day, value: 1, to: currentDate)!
guard let bodyMass = HKObjectType.quantityType(forIdentifier: .bodyMass),
let bodyMassIndex = HKObjectType.quantityType(forIdentifier: .bodyMassIndex),
let bodyFatPercentage = HKObjectType.quantityType(forIdentifier: .bodyFatPercentage) else {
return
}
ProfileDataStore.getSamples(for: bodyMassIndex,unit: HKUnit.count()) { (sample, error) in
guard let sample = sample else {
return
}
let entry = WeightEntry(date: currentDate, value: sample)
let timeline = Timeline(entries: [ entry ], policy: .after(refreshDate))
completion(timeline)
}
}