How to request permission and access HealthKit data
How to read HealthKit data
How to write data to HealthKit’s central repository
授權
//3. Prepare a list of types you want HealthKit to read and write
let healthKitTypesToWrite: Set<HKSampleType> = [bodyMassIndex,
activeEnergy,
HKObjectType.workoutType()]
let healthKitTypesToRead: Set<HKObjectType> = [dateOfBirth,
bloodType,
biologicalSex,
bodyMassIndex,
height,
bodyMass,
HKObjectType.workoutType()]
//4. Request Authorization
HKHealthStore().requestAuthorization(toShare: healthKitTypesToWrite,
read: healthKitTypesToRead) { (success, error) in
completion(success, error)
}
讀
class func getMostRecentSample(for sampleType: HKSampleType,
completion: @escaping (HKQuantitySample?, Error?) -> Swift.Void) {
//1. Use HKQuery to load the most recent samples.
let mostRecentPredicate = HKQuery.predicateForSamples(withStart: Date.distantPast,
end: Date(),
options: .strictEndDate)
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate,
ascending: false)
let limit = 1
let sampleQuery = HKSampleQuery(sampleType: sampleType,
predicate: mostRecentPredicate,
limit: limit,
sortDescriptors: [sortDescriptor]) { (query, samples, error) in
//2. Always dispatch to the main thread when complete.
DispatchQueue.main.async {
guard let samples = samples,
let mostRecentSample = samples.first as? HKQuantitySample else {
completion(nil, error)
return
}
completion(mostRecentSample, nil)
}
}
HKHealthStore().execute(sampleQuery)
}
寫
class func saveBodyMassIndexSample(bodyMassIndex: Double, date: Date) {
//1. Make sure the body mass type exists
guard let bodyMassIndexType = HKQuantityType.quantityType(forIdentifier: .bodyMassIndex) else {
fatalError("Body Mass Index Type is no longer available in HealthKit")
}
//2. Use the Count HKUnit to create a body mass quantity
let bodyMassQuantity = HKQuantity(unit: HKUnit.count(),
doubleValue: bodyMassIndex)
let bodyMassIndexSample = HKQuantitySample(type: bodyMassIndexType,
quantity: bodyMassQuantity,
start: date,
end: date)
//3. Save the same to HealthKit
HKHealthStore().save(bodyMassIndexSample) { (success, error) in
if let error = error {
print("Error Saving BMI Sample: \(error.localizedDescription)")
} else {
print("Successfully saved BMI Sample")
}
}
}
The bundle identifier of the entry if made manually will be com.apple.Health, which is the bundle identifier of the Health app. Notice the capital H. When you pull your data just ignore the data which has a bundle identifier of com.apple.Health.
That way you will be only considering activities which are not manual
(lldb) po samples[1].source.bundleIdentifier
"com.apple.health.6AE18D38-5413-4679-BDBA-7FBD1DA9A45C"
(lldb) po samples[1].source.name
"電商科的iPhoneX"
(lldb) po samples[1].metadata
nil
手動輸入
(lldb) po samples[2].source.bundleIdentifier
"com.apple.Health"
(lldb) po samples[2].source.name
"健康"
(lldb) po samples[2].metadata
▿ Optional<Dictionary<String, Any>>
▿ some : 1 element
▿ 0 : 2 elements
- key : "HKWasUserEntered"
- value : 1
//1. Get all workouts with the "Other" activity type.
let workoutPredicate = HKQuery.predicateForWorkouts(with: .other)
//2. Get all workouts that only came from this app.
let sourcePredicate = HKQuery.predicateForObjects(from: HKSource.default())
//3. Combine the predicates into a single predicate.
let compound = NSCompoundPredicate(andPredicateWithSubpredicates: [workoutPredicate,
sourcePredicate])