HealthKit为iPhone和Apple Watch上的健康和健身数据提供了一个中央存储库。在用户的许可下,应用程序与HealthKit商店通信,以访问和共享这些数据
关于HealthKit Framework
HealthKit框架旨在以一种有意义的方式在应用程序之间共享数据。框架将数据和单元的类型限制在一个预定义的列表中,确保所有应用程序都理解数据的含义以及如何使用数据。开发人员不能创建自定义数据类型或单元。相反,HealthKit提供了多种数据类型和单元。
此外,框架使用大量子类,产生类似类的深层层次结构。通常,这些类之间有细微但重要的区别。例如,HKQuantitySample对象用于存储带有数值的数据,而HKCategorySample对象用于存储从枚举中选择的值。
HealthKit Data
HealthKit保存了多种数据类型:
Characteristic data(特征数据): 这些记录表示通常不会更改的项,例如用户的生日、血型、生物性别和皮肤类型。可以使用
dateOfBirthWithError:
、bloodTypeWithError:
、biologicalSexWithError
:和fitzpatrickSkinTypeWithError:
方法直接从HealthKit读取该数据。应用程序无法保存特征数据。用户必须使用Health App输入或修改这些数据。Sample data(样本数据): 用户的大多数健康数据存储在表示特定时间点数据的sample中。所有sample类都是HKSample类的子类,它是HKObject类的子类。
Workout data(训练数据): 有关健身及运动的资料以
HKWorkout
的形式储存。虽然HKWorkout是HKSample的一个子类,但是它的行为与其他sample子类有些不同。Source data(源数据): 每个样本都存储有关其来源的信息。
HKSourceRevision
对象包含有关App或设备的信息。HKDevice
对象包含生成相关数据的硬件设备的信息。Deleted objects(删除对象):
HKDeletedObject
实例用于临时存储已从HealthKit存储中删除的项目的UUID。 当用户或其他应用程序删除对象时,可以使用Deleted objects
进行响应。
对象和样本的属性
HKObject
类是所有HealthKit
样本类型的父类。 所有HKObject
子类都是不可变的。 每个对象都具有以下属性:
UUID: 唯一标识符。
Metadata: 包含有关条目的其他信息的字典。 元数据可以包含预定义和自定义的key。 预定义的key有助于在App之间共享数据。 自定义key有助于扩展HealthKit对象类型,将特定App的数据添加到条目中。
Source Revision: 样本的来源。 来源可以是直接将数据保存到HealthKit或App的设备。 当保存对象到HealthKit时,HealthKit会自动记录每个对象的来源和版本。 此属性仅适用于从Health商店检索到的对象。
Device: 生成此样本中存储数据的硬件设备。
HKSample
类是HKObject
的子类。 样本对象表示特定时间点的数据,所有样本对象都是HKSample
类的子类。
HKSample
进一步划分为四个具体子类:
Category samples(分类样本): 可以分类为有限类别的数据。
Quantity samples(数量样本): 可以存储为数值的数据。 数量样本是HealthKit中最常见的数据类型。 包括用户的身高和体重,以及其他数据,如步数,用户的体温和脉搏率
Correlations(相关性) 包含一个或多个样本的复合数据。 在iOS 8.0中,HealthKit使用相关性来表示食物和血压。 在创建食物或血压数据时,应始终使用相关性。
Workouts(锻炼): 表示身体活动的数据,如跑步,游泳,甚至比赛。 Workouts通常具有
type, duration, distance, energy burned
属性
线程
HealthKit存储是线程安全的,大多数HealthKit对象是不可变的。 通常,可以在多线程环境中安全地使用HealthKit。
所有HealthKit API的完成处理都在私有后台队列上执行。 在更新用户界面或修改只应由主线程触及的任何其他资源之前,通常需要将此数据分发回主队列。
设置HealthKit
在使用HealthKit之前,必须执行以下步骤:
- 在您的应用中启用HealthKit。
- 确保当前设备上的HealthKit可用。
- 创建应用程序的HealthKit商店。
- 请求读取和共享数据的权限。
开启HealthKit
在使用HealthKit之前,必须为应用添加HealthKit功能。 在Xcode中,选择项目并打开HealthKit功能
确保HealthKit的可用性
调用isHealthDataAvailable
方法来确保HealthKit在用户设备上是否可用。
if HKHealthStore.isHealthDataAvailable() {
// Add code to use HealthKit here.
}
在调用HealthKit其他方法之前先调用该方法。如果设备上没有HealthKit(比如在iPad上),调用其他的方法会报errorHealthDataUnavailable
错误;如果HealthKit受限制(比如,在企业环境中),调用其他方法会报errorHealthDataRestricted
错误。
创建HealthKit Store
如果HealthKit可用且已经开启,实例化一个HKHealthStore
对象:
let healthStore = HKHealthStore()
每个App只需要一个HealthKit Store,它是long-lived 对象。
请求读取和共享数据的权限
为了保护用户的隐私,HealthKit需要精细的授权。在尝试保存和访问数据之前,必须申请读取和分享数据的权限。
注意: 用户可以随时在设置或健康App中修改你的App的权限,你的App将会显示在健康App的数据来源页面。
此外,还需要在info.plist文件中设置两个key:
- NSHealthShareUsageDescription:读取数据的描述
- NSHealthUpdateUsageDescription:写入数据的描述
如果用户同意共享某种类型的数据,则可以创建该类型的样本并将其保存到HealthKit Store中。但是,在保存任何数据之前,最好调用authorizationStatusForType:
方法来检查是否有该权限。如果还没有申请过该权限,保存数据将会抛出HKErrorAuthorizationNotDetermined
错误。如果用户拒绝了该权限申请,尝试保存数据将会抛出HKErrorAuthorizationDenied
错误。
为了保护用户隐私,我们的App将不会知道用户是否授权或者拒绝读取HealthKit的权限。如果用户拒绝了,那在从HealthKit中查询数据时,将只会返回我们自己的App成功保存到HealthKit Store的样本数据。
指定所需的临床记录类型
如果App需要访问特定的临床记录数据才能正常运行,在info.plist文件中添加NSHealthRequiredReadAuthorizationTypeIdentifiers
key,该key定义了app必须拥有读取权限的数据类型。
保存数据到HealthKit
我们的App可以创建新的样本,并将其保存到HealthKit Store。尽管所有的样本类型都遵守相似的过程,但每种类型都有自己的变体:
查找数据的类型标识符。比如,要记录用户的体重,使用
HKQuantityTypeIdentifierBodyMass
类型标识符,有关类型标识符的完整列表,可以查看Data Types使用
HKObjectType
类的方法创建正确的对象类型。比如,要保存用户的体重,需要使用quantityTypeForIdentifier:
方法来创建HKQuantityType
对象。方法列表可以参阅HKObjectType使用对象类型实例化相匹配的
HKSample
子类对象使用
saveObject:withCompletion:
方法将对象保存到HealthKit Store
每个HKSample
子类都有自己的便捷方法来实例化对象,
对于数量样本,创建HKQuantity
类的实例。数量的单位必须与类型标识符文档中描述的单位想对应。比如,HKQuantityTypeIdentifierHeight
声明长度单位,因此,数量必须使用厘米,米,英尺或英寸或者其他兼容的单位。可以参阅HKQuantitySample
对于类别样本(category samples),样本的值必须与类型标识符文档中声明的枚举相对应。比如,HKCategoryTypeIdentifierSleepAnalysis
表明它使用HKCategoryValueSleepAnalysis 枚举。因此,在创建此样本时,必须从该枚举中选值。更多信息可以参阅HKCategorySample
性能与细节
将数据保存到HealthKit Store时,通常需要在使用单个样本表示数据还是多个较小样本之间拆分数据做选择。从性能角度来说,使用单个样本更好,但是,多个样本可以让用户更详细的了解他们的数据如何随时间变化。理想情况是能够找到合适的样本大小,以便为用户提供有用的历史数据。
在记录锻炼数据时,可以使用高频数据(每分钟一个样本)来提供强度图标,并以其他方式分析用户在锻炼中的表现。对于不太密集的活动,比如每日步数,一小时或者更短时间的样本通常更好一些。
App应该避免保存24小时或更长时间的样本。
使用健康App中的数据
健康App允许用户访问其HealthKit Store中的所有数据。用户可以查看、添加、删除和管理他们的数据。
具体来说,用户可以
查看包含他们当前健康数据的仪表盘
访问所有存储在HealthKit中的数据。用户可以按类型、app或设备查看数据
管理每个app访问和读取HealthKit Store的权限
因此,健康App对开发HealthKit有一些重要影响。用户可以在我们的app之外修改数据,甚至修改我们app的读写权限,因此,我们的应用应该始终查询HealthKit Store中的当前数据
其次,我们也可以在健康App中查看我们的app保存到Health Store的数据。这在早期测试中很有用。
从HealthKit读取数据
有三种主要的方法来从HealthKit Store读取数据
直接调用方法。 HealthKit store提供了直接读取特征(characteristic)数据的方法。这些方法只能用来读取特征数据。更多信息可以看下HKHealthStore
Queries(查询) Queries返回从HealthKit Store请求的数据的当前快照。
Long-running queries 这类查询将在后台持续运行,并且在对HealthKit Store进行更改时更新我们的app
Queries(查询)
Queries返回HealthKit Store中数据的当前快照(snapshot)。所有的queries都是在匿名后台队列运行的。当queries完成后,他将在后台队列上处理结果。HealthKit提供了不同类型的queries来返回不同类型的数据。
Sample query(样本查询): 这是一个通用查询,使用样本查询来访问任意类型的样本数据。当需要对结果进行排序,或者限制返回的样本数量时,样本查询非常有用。更多的可以查询HKSampleQuery
Anchored object query(锚定对象查询): 使用此查询可以搜索已经添加到HealthKit Store,或者从其删除的item。第一次运行锚定查询时,将返回当前Store中所有匹配的样本。在后续运行中,将只返回自上次运行以来添加或删除的item。更多信息可以参阅HKAnchoredObjectQuery
Statistics query(统计查询): 使用此查询对匹配的样本集合进行统计计算。可以使用统计查询来计算总和、最小值、最大值以及平均值。更多信息可以查阅HKStatisticsQuery
Statistics collection query(统计收集查询): 使用此查询可以在一系列多个固定长度的时间间隔内执行多个统计查询。在创建图形时会经常用到这些。它们提供了一种简单的方法来计算一些事情,比如每天消耗的卡路里总数或者每五分钟的步数。更多信息可以查阅HKStatisticsCollectionQuery
Correlation query(相关查询): 使用此查询可以对correlation中的数据进行复杂搜索。这些查询可以包含存储在correlation中的每个样本类型的各个谓词。更多可以查阅HKCorrelationQuery
Source query(来源查询): 可以查询匹配样本的来源(app或者设备)。该查询列出了保存特定样本类型的所有来源。更多信息可以查阅HKSourceQuery
Activity summary query: 使用该查询可以搜索用户的活动概要信息。每个Activity summary对象包含了给定日期的用户的活动总结。可以查询一天或者多天的数据。更多信息可以查阅HKActivitySummaryQuery
Document query(档案查询): 使用此查询来搜索健康档案。更多信息可以查阅HKDocumentQuery
Long-Running Queries
Long-running queries 会在匿名后台队列持续运行,并在对HealthKit Store进行更改时更新我们的app。另外,observer queries可以注册为后台交付。这样,当发生更新时,HealthKit就会在后台唤醒我们的app。
HealthKit 提供以下的long-running queries:
Observer query(观察者查询): 该查询将监视HealthKit Store,匹配到的样本进行更改时也会通知用户。当希望收到HealthKit Store的相关修改时可以使用观察者查询。更多信息可以查阅HKObserverQuery
Anchored object query(锚定对象查询): 除了返回数据的当前快照之外,锚定对象查询还可以作为一个Long-running queries。如果启用了该查询,它将在后台持续运行,在匹配的样本被添加到或从Store中删除时提供更新。不像观察者查询,这些更新包含了已添加或者已删除的项目列表。但是,锚定对象查询无法注册为后台提交。更多信息可以查阅HKAnchoredObjectQuery
Statistics collection query 除了计算统计几个的当前快照外,该查询还可以作为一种long-running query。如果将匹配的样本添加到Store或者从中删除,该查询将会重新计算统计集合,并更新我们的app。Statistics collection queries 不能注册为后台提交。更多信息可以查阅HKStatisticsCollectionQuery
Activity summary query: 除了计算用户活动的当前快照之外,该查询也可以作为一种 long-running query。如果用户的活动概要数据改变,该查询将会重新计算活动概要,并更新我们的app。Activity summary query也无法注册为后台提交。更多信息可以查阅HKActivitySummaryQuery
数据类型
HealthKit使用HKObjectType
的子类来标识存储在HealthKit中数据的不同类型:
HKCharacteristicType
表示通常不会随时间变化的数据(例如血型)。HKQuantityType
表示包含数值的样本(例如所消耗的卡路里)。HKCategoryType
表示包含简短列表中选项的样本(例如睡眠分析)。HKCorrelationType
表示包含多个数量或类别样本的复杂样本(例如,包含多个营养样本的食物样本)HKWorkoutType
代表锻炼及其相关数据。其他对象类型(例如,
HKActivitySummaryType、HKDocumentType
和HKSeriesType
)表示其他专门的数据类型
创建类型对象,需要调用相应的HKObjectType
类方法,并传入所需的类型标识。
let bloodType = HKObjectType.characteristicType(forIdentifier: .bloodType)
let caloriesConsumed = HKObjectType.quantityType(forIdentifier: .dietaryEnergyConsumed)
let sleepAnalysis = HKObjectType.categoryType(forIdentifier: .sleepAnalysis)
可以使用生成的对象类型来请求访问数据的权限,将新数据保存到HealthKit存储中或从HealthKit存储中读取数据。
Sample
大部分健康和健身数据是使用HKSample
的子类来保存到HealthKit Store中。所有的Sample
子类都在指定的时间记录信息。如果sample
的startDate
和endDate
属性相同,则样本表示时间点。如果endDate
在startDate
之后,则样本表示一个时间间隔。
HealthKit使用不同的HKSample
子类来存储不同类型的数据:
HKQuantitySample
(数量样本) 对象存储quantity
-一个数值和单位。大部分HealthKit数据类型使用数量样本。比如,身高,心率以及饮食能量消耗都适用数量样本。HKCategorySample
对象存储从简短列表中选择的单个选项。例如睡眠数据(用户可以躺在床上,睡着或者醒着)。HKCorrelation
样本将两个或者多个样本合并为单个值。比如,使用该样本表示食物和血压。食物样本包含任意数量的nutrition
(营养)样本,而血压样本包含systolic
(心脏收缩)和diastolic
(心脏舒张)样本HealthKit还使用其他
Sample
子类来表示更专业的数据类型。 例如,HKCDADocumentSample
,HKWorkoutRoute
和HKWorkout
。
文章来源:https://developer.apple.com/documentation/healthkit?language=objc