文章目录
- 一、简介
- 二、权限配置
- 1. 在开发者账号中勾选HealthKit
- 2. 在targets的capabilities中添加HealthKit。
- 3. infoPlist需要配置权限
- 三、创建健康数据管理类
- 1. 引入头文件
- 2. 健康数据读写权限
- 3. 检查权限
- 4. 读取步数数据
- 5. 写入健康数据
- 四、运行获取权限页面
一、简介
HealthKit是一款用于搜集和办理医疗和健康相关数据的开发工具包,它为开发者供给了拜访用户健康数据的API和框架,并使得这些数据能够与iOS设备上的其他应用程序相互共享。
HealthKit允许应用程序搜集和办理各种类型的健康数据,包含身体丈量数据(如体重、身高和心率)、健身数据(如步数和距离)、饮食数据、睡觉数据和心理健康数据等。这些数据能够从多个来历搜集,如从硬件设备(如智能手表、智能手机和健身跟踪器)中获取,或由用户手动输入。
二、权限配置
1. 在开发者账号中勾选HealthKit
2. 在targets的capabilities中添加HealthKit。
3. infoPlist需要配置权限
Privacy - Health Share Usage Description
需要您的同意,才能访问健康更新,给您带来更好的服务
Privacy - Health Update Usage Description
需要您的同意,才能分享健康数据,给您带来更好的服务
注意:iOS13 这里描述太粗糙,会导致程序崩溃。
三、创建健康数据管理类
1. 引入头文件
import HealthKit
2. 健康数据读写权限
// 写权限
private func dataTypesToWrite() -> Set<HKSampleType> {
// 步数
let stepCountType = HKObjectType.quantityType(forIdentifier: .stepCount)
// 身高
let heightType = HKObjectType.quantityType(forIdentifier: .height)
// 体重
let weightType = HKObjectType.quantityType(forIdentifier: .bodyMass)
// 活动能量
let activeEnergyType = HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)
// 体温
let temperatureType = HKObjectType.quantityType(forIdentifier: .bodyTemperature)
// 睡眠分析
let sleepAnalysisType = HKObjectType.categoryType(forIdentifier: .sleepAnalysis)
let setTypes = Set([stepCountType, heightType, weightType, activeEnergyType, temperatureType, sleepAnalysisType].compactMap { $0 })
return setTypes
}
// 读权限
private func dataTypesToRead() -> Set<HKObjectType> {
// 步数
let stepCountType = HKObjectType.quantityType(forIdentifier: .stepCount)
// 身高
let heightType = HKObjectType.quantityType(forIdentifier: .height)
// 体重
let weightType = HKObjectType.quantityType(forIdentifier: .bodyMass)
// 体温
let temperatureType = HKObjectType.quantityType(forIdentifier: .bodyTemperature)
// 出生日期
let birthdayType = HKObjectType.characteristicType(forIdentifier: .dateOfBirth)
// 性别
let sexType = HKObjectType.characteristicType(forIdentifier: .biologicalSex)
// 步数+跑步距离
let distance = HKObjectType.quantityType(forIdentifier: .distanceWalkingRunning)
// 活动能量
let activeEnergyType = HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)
// 睡眠分析
let sleepAnalysisType = HKObjectType.categoryType(forIdentifier: .sleepAnalysis)
let setTypes = Set([stepCountType, heightType, weightType, activeEnergyType, birthdayType, sexType, distance, temperatureType, sleepAnalysisType].compactMap { $0 })
return setTypes
}
3. 检查权限
/// 检查是否支持获取健康数据
public func authorizeHealthKit(_ compltion: ((_ success: Bool, _ error: Error?) -> Void)?) {
guard HKHealthStore.isHealthDataAvailable() == true else {
let error = NSError(domain: "不支持健康数据", code: 2, userInfo: [NSLocalizedDescriptionKey: "HealthKit is not available in th is Device"])
if let compltion = compltion {
compltion(false, error)
}
return
}
let writeDataTypes = dataTypesToWrite()
let readDataTypes = dataTypesToRead()
healthStore.requestAuthorization(toShare: writeDataTypes, read: readDataTypes) { success, error in
if let compltion = compltion {
compltion(success, error)
}
}
}
4. 读取步数数据
/// 获取步数
public func getStepCount(_ completion: @escaping ((_ stepValue: String?, _ error: Error?) -> Void)) {
// 要检索的数据类型。
guard let stepType = HKObjectType.quantityType(forIdentifier: .stepCount) else {
let error = NSError(domain: "不支持健康数据", code: 2, userInfo: [NSLocalizedDescriptionKey: "HealthKit is not available in th is Device"])
completion(nil, error)
return
}
// NSSortDescriptors用来告诉healthStore怎么样将结果排序。
let start = NSSortDescriptor.init(key: HKSampleSortIdentifierStartDate, ascending: false)
let end = NSSortDescriptor.init(key: HKSampleSortIdentifierEndDate, ascending: false)
/*
@param sampleType 要检索的数据类型。
@param predicate 数据应该匹配的基准。
@param limit 返回的最大数据条数
@param sortDescriptors 数据的排序描述
@param resultsHandler 结束后返回结果
*/
let query = HKSampleQuery.init(sampleType: stepType, predicate: HealthKitManager.getStepPredicateForSample(), limit: HKObjectQueryNoLimit, sortDescriptors: [start, end]) { _, results, error in
guard let results = results else {
completion(nil, error)
return
}
print("resultCount = \(results.count) result = \(results)")
// 把结果装换成字符串类型
var totleSteps = 0
results.forEach({ quantitySample in
guard let quantitySample = quantitySample as? HKQuantitySample else {
return
}
let quantity = quantitySample.quantity
let heightUnit = HKUnit.count()
let usersHeight = quantity.doubleValue(for: heightUnit)
totleSteps += Int(usersHeight)
})
print("最新步数:\(totleSteps)")
completion("\(totleSteps)", error)
}
healthStore.execute(query)
}
5. 写入健康数据
/// 写入数据
public func writeStep() {
let steps = HKObjectType.quantityType(forIdentifier: .stepCount)!
let quantity = HKQuantity(unit: HKUnit.count(), doubleValue: 1000)
let now = Date()
let start = now.addingTimeInterval(-3600 * 24)
let end = now
let sample = HKQuantitySample(type: steps, quantity: quantity, start: start, end: end)
let healthStore = HKHealthStore()
healthStore.save(sample) { (success, _) in
if success {
// 数据已写入 HealthKit
} else {
// 写入数据失败
}
}
}