大多数浏览器和
Developer App 均支持流媒体播放。
-
用 HealthKit 同步健康数据
HealthKit 为你提供在任何地方都能智能管理健康数据的工具,无论是多个支持 HealthKit 的设备(如 iPhone 和 Apple Watch),还是外部服务器,都可通过护理团队共享数据。本节内容中,我们将深入探讨通过 HealthKit 内置的 sync identifier 元数据管理数据版本,如何使用 HKAnchoredObjectQuery 检测健康数据中的变化,并介绍确保在任何地方都能得正确数据的最佳方法。
资源
相关视频
WWDC23
WWDC20
-
下载
(你好 WWDC 2020) 大家好 欢迎参加 WWDC
大家好 欢迎观看 “用 HealthKit 同步健康数据” 我是 Netra HealthKit 团队的软件开发工程师 我们的用户将他们最隐私的个人信息 以健康数据的方式 存储在我们的设备上 在 Apple 的各大平台 HealthKit 作为基础 不仅能够便于你对这些数据进行访问 而且能够实现你在 app 中创建的 所有丰富体验 我们都是 这个庞大健康生态系统中的一部分 健康生态系统旨在赋予用户更多的权利 用户可以从生态系统的任何一端 访问其健康数据 例如 Apple Watch、Apple 发布的 app 以及所有你们创建的优质 app 同样 我们从不希望用户 对健康数据的更改感到惊讶 虽然我们所有人都希望 成为健康生态系统的良好公民 但这并不简单 在本次讲座中 我们将通过 HealthKit 专门帮助大家解决这一问题 请记住 我们的目标 是赋予用户更多的权利 用户必须始终掌控个人数据 同时健康数据的更改 也必须始终如实反映用户意图
今天 我们将讨论两大重要话题 首先 我们会了解 HealthKit 中的监测更改 我们知道 生态系统的任何一端 都可以读取或编写数据 我们可以将健康数据用于 支持多种类型的 app 或数据可视化 app 必须能够恰好地响应 HealthKit 中的更改
其次 我们将深入探讨 如何保持外部数据存储 与 HealthKit 同步 我们将学习 HealthKit 能够带来哪些便利
我们从第一个话题开始 HealthKit 中的监测更改 让我们构建一款能够贯彻相关概念的 app 这款 app 将帮助患者伤后恢复 并允许患者追踪个人每日步数 随着时间的推移 患者会希望监测每日步数是否增加 另外 他们一周内还会多次拜访 物理治疗师 完成特定的步行测试 检查他们在六分钟内的步行距离 测试将测量患者在平面上 步行六分钟的行走距离 之后 物理治疗师会将测试结果输入机器 同时 数据将以每周报告的形式 同步至用户的 iPhone
图表是监控这些重要数据的最佳方式之一 患者能够轻松了解 其步数是呈上升还是下降趋势 无需太过关注实际数值 在这里 我们提供了一张患者和物理治疗师 都很感兴趣的图表 该图表追踪了患者 在过去一周内的每日总步数 步数可以 记录在 Apple Watch 和 iPhone 中 我们希望确保能够获得准确的每日步数 在创建这样的图表时 首先需要 使用 HKStatisticsCollectionQuery 这是在创建大多数图表的过程中 第一个需要使用的查询 你可能在我们之前的讲座 “HealthKit 新手指南”中 了解了该查询的所有内容 如果没有 并对它感到陌生的话 可以先去观看该视频 实际上 我们将使用该会话中 创建的 SmoothWalker app 构建 app 我们刚刚创建的图表 需要发送至远程服务器 以便物理治疗师在对用户进步感兴趣时 能够读取相关数据 具体是怎样的场景呢? (图表数据) 首先 我们会将一周的初始图表发送至服务器
(最新统计结果) 接着 如果一周数据发生变化 例如 收集到的步数增加 那么 一周的最新数据将发送至服务器 为了达到我们的目的 我们将外部数据视为远程服务器 不过也可能是在设备上进行本地维护的 外部数据库 它可以使用 Core Data 甚至是 SQLite 数据库
我们知道 可以使用 HKStatisticsCollectionQuery 加载数据 我们需要定期运行该查询 获取最新数据 可能是在启动 app 时进行 也可能是在启动之后 每隔几个小时进行 然而 在使用该查询响应最新变化时 也存在一些缺点 如果数据变化不频繁 我们就需要多次运行 HKStatisticsCollectionQuery 导致计算冗余
同时 每一次我们都需要发送所有数据 这将造成网络资源浪费 针对这样的用例 HealthKit 提供了另一种工具 名为 HKAnchoredObjectQuery HKAnchoredObjectQuery 允许我们监控健康数据库中的更新情况 它可以提供健康数据库变化的截图 包含新样本和已删除样本 让我们了解下该查询如何运作
顾名思义 锚定对象查询需要锚点 锚点代表健康数据库 在演变过程中的特定时间点 健康数据可能 在该时间点之后被添加或删除
该锚点将帮助识别 从该查询中最新接收的所有样本 向 HealthKit 添加锚点后 HealthKit 便只会 返回该时间点之后的变化
首先 在第一个查询中 锚点将为空值 HealthKit 将拥有 A、B、C 三个样本 (执行) 执行该查询后 HealthKit 将参照指定的数据类型 返回所有数据 在这种情况中 updateHandler 将接收 A、B、C 三个样本 (新锚点) 更新锚点后 HealthKit 将在 updateHandler 中 提供新锚点
即 HealthKit 在 updateHandler 中 返回样本的最后时间点
假设在上一次调用 updateHandler 后 样本增加 例如样本 D 和样本 E 同时 样本 B 被删除 在随后的每一次运行查询过程中 系统只会将在先前锚点之后的变化 返回至 updateHandler 例如增加样本 D 和样本 E 样本 B 被删除 样本 A 和样本 C 没有变化
在 HealthKit 中使用 HKAnchoredObjectQuery 或任何查询时 必须考虑正在处理的 数据类型和用例 在步数场景中 我们并不关心实际的样本本身 Apple Watch 在五年前发布 这些设备不断产生了大量数据 需要同步的数据非常多 我们只希望获得累计统计结果 而不是所有样本
在其他场景中 我们也会关注独立样本 那些偶尔生成的样本 每种数据类型能够以不同的方式进行处理 我们必须花时间思考如何执行查询 以及如何同步数据 完成此任务将产生我们期待的查询类型
同时 查询最少数据在性能上也有优势 在当前用例中 我们只希望物理治疗师能够使用统计图表 那么 我们如何实现这一点? 我们可以始终运行 HKAnchoredObjectQuery 中的样本 并计算图表 但是 为什么不将两种查询组合使用呢? 通过锚定对象查询 我们可以将谓词和样本类型 精确设置为希望寻找的内容 当锚定对象查询 更新 HealthKit 中的变化时
你可以查看返回样本的日期 并通过其创建并运行统计收集查询
之后 返回的相应天数内的统计结果 可以作为更新后的图表数据 发送至远程计算机
现在 我们将最新数据发送至服务器 同样 其可能是本地 Core Data 模型 或远程服务器的 NSURLSession 为了更好地理解 我们将学习在代码中的具体场景
首先 我们需要为锚定对象查询设置参数 样本类型为步数 我们将使用 PersistedAnchor 设置锚点参数 将锚点持久化可以允许我们只取回 上次查询之后 HealthKit 的变化
initialResultsHandler 和 updateHandler 需要执行同样的操作 因此 我们将为处理程序变量设置相同的阻塞
在处理程序中 我们将开启从 HealthKit 返回的样本
并通过他们创建谓词 例如取回样本的日期 我们将使用此谓词 初始化统计收集查询
在这里 我们还需要更新 PersistedAnchor
在该阻塞的最后 我们可以调用 fetchStatistics 方法 该方法使用该谓词 创建 HKStatisticsCollectionQuery
我们将使用设置的参数 初始化 HKAnchoredObjectQuery 例如样本类型、空值谓词、锚点 以及 resultsHandler 和 updateHandler
最后 在 healthStore 上执行查询
让我们了解下 fetchStatistics 方法 如何创建 HKStatisticsCollectionQuery 同样 我们需要设置参数 我们希望统计收集查询 能够按天进行桶排序 为此 我们将锚点日期设置为周一午夜 区间参数为一天 同样 样本类型为步数
之后 便可以通过这些参数 初始化 HKStatisticsCollectionQuery 由于我们希望获取每日总步数 因此选项为 cumulativeSum 正如大家所看到的 在这里 我们提供了锚定对象查询中创建的谓词
在 initialResultsHandler 中 我们会开启 statisticsCollection 之后 只需要将该数据发送至远程服务器即可
和往常一样 只有在 healthStore 上 执行查询后 才可获得更新数据
刚刚 我们了解了如何将数据 从 HealthKit 发送至外部服务器 现在 让我们进入下一步 即 从外部存储接收数据 并将其同时保存至 HealthKit
和我们之前了解的一样 患者在一周内会多次前往 物理治疗师的办公室 完成六分钟的步行测试 测试会检查 患者在平面上 步行六分钟的行走距离 通常 物理治疗师会通过测试结果 衡量患者的锻炼能力
今年 我们在 HealthKit 中 引入了一套新的移动类型 六分钟步行测距就是其中一种 这些数据类型很有利于 app 目标的实现 我们可以 将从物理治疗师那接收的测试数据 保存为六分钟的步行测距样本 在 app 中 物理治疗师会记录 六分钟步行测试结果的数值 之后 相应的每周报告将同步至患者设备 每周报告中包含一张图表 显示一周内的 每日六分钟步行测距
此外 我们还包含图表中展示的独立样本 这是为了便于物理治疗师或患者 深入了解每一次测试结果 这就又回到了之前的想法 即 需要以不同的方式处理每个数据类型 我们必须思考 正在处理的数据类型以及用例 sixMinuteWalkTestDistance 不会频繁写进 HealthKit 中 但患者和物理治疗师 可能对每个独立测试样本感兴趣 因此 与我们之前了解的步数不同 此时我们需要在图表中绘制出所有样本 之前 我们将步数样本 从设备同步至远程服务器 现在 每周报告包含在物理治疗师的服务器中 我们希望将其从该服务器 同步至患者设备 并在 HealthKit 中保存相应样本
这将帮助患者在 app 中查看其 sixMinuteWalkTestDistance 图表 以及独立测试样本 将变化保存至 HealthKit 时 需要牢记几点 我们只希望 在 HealthKit 中保存增量样本 简单地移除并重新保存所有数据 会导致用户健康数据的状态不一致 新样本反映的是用户最新的健康数据 例如 最新的六分钟步行测试或最新步数 甚至是用户记录的体重变化
在删除样本时 需要确保该样本确实是 你的 app 之前编写的样本 切勿删除之前未显式保存的数据 最佳做法是 先查询样本 再进行删除
增删样本应当始终如实反映用户意图 如果用户不希望删除样本 最好就不要这么做
在这里 我们会遇到一些挑战 如果物理治疗师希望更新特定测试 我们应该怎么做? 例如 在 6 月 18 号的测试中 患者在六分钟步行测试中行走了 400 米 之后 物理治疗师为了提出错误 更新了该数据 实际行走距离为 450 米 此时 问题十分复杂 在编辑样本时 需要切实删除并添加新样本 否则可能会保存重复样本 这意味着你必须查询该样本 并将其与物理治疗师 之前编辑的样本准确匹配 之后 再保存新样本 如果无需编辑其他样本 那么就要确保在变化过程中 不会为了其中任何一个变化保存重复样本 所有患者设备都可以使用健康数据 例如 iPhone 和 Apple Watch 样本中的变化需要如实反映在所有设备中 当你在一款设备上保存了样本后 需要确保 不用在另一款设备上再次保存相同的样本
此时 必须确保如实反映用户意图 这听起来似乎非常复杂 但是 HealthKit 能够 帮助你轻松解决这一问题 HealthKit 包含两个元数据密钥 即 HKMetadataSyncIdentifier 和 HKMetadataSyncVersion 同步标识符为字符串 版本为数字 该标识符允许所有用户设备 识别健康生态系统内 任何位置的样本 而版本则会帮助我们了解样本更新的时间
当你在样本上设置同步标识符时 HealthKit 会确保样本的重复副本 不会保存在用户健康数据库中 而组合使用同步标识符和版本 则可以限制 HealthKit 只在版本号增加时更新样本 另外 使用同步标识符完成的所有操作 均为事务安全的 这意味着 如果出现错误 你完全不必担心 数据绝对处于一致状态 所有用户设备都可以使用健康数据 同步标识符将帮助你在不同设备中 将所有样本保持在一致状态 远程服务器 包含带有标识符和版本的样本 app 会将样本从远程服务器 同步至患者的 iPhone
而 HealthKit 则会 将该样本视为首个样本并加以保存
当 HealthKit 意识到保存新样本后 就会将其同步至患者的所有设备 如果患者使用 Apple Watch 就同步至 Watch
如果远程服务器同时也 向 Watch 上的 app 同步数据 那么 在你尝试再次保存该样本后 HealthKit 将判定该样本已经存在 并加以忽视 现在 如果物理治疗师 决定更新六分钟步行测试中 行走的距离 我们将相应更新样本 保持同步标识符不变 但增加版本号
当该样本同步至患者设备后 HealthKit 会注意到版本号已经增加
并使用新样本覆盖旧样本
同样 新样本会再次 同步至患者的所有设备
如果远程服务器将第二版本的样本 同步至 Apple Watch HealthKit 会判定该样本已经存在 并进行忽视 可以想见 HealthKit 负责管理保存与同步中 所有的冲突解决 版本划分与同步这一挑战已经简化到 只需要将标识符保持一致即可 之前 我们查看了患者每周报告 那么 我们如何进行数据建模呢? 一种方法是 可以将每周报告表示为报告类 该报告类可以 通过高级别同步标识符进行标识 它将包含一份列表 涵盖当周所有的 sixMinuteWalkTestDistance 样本
之后 每个样本 将包含同步标识符元数据密钥 该密钥派生于高级别报告标识符
这样 在不同的周 就可以引用各不相同的样本 数据能以报告类模型的形式 从远程服务器同步至患者设备 同时 该列表中的独立 HK 样本 也可以保存至 HealthKit
让我们通过演示版本进一步了解 在之前“HealthKit 新手指南”讲座中 我们已经创建了 SmoothWalker app 该项目可以从 Developer 网站下载 用作样本代码 我们希望 在 app 中创建每周报告视图控制器 点击 Fetch 按钮后 我们希望能够 从服务器中提取六分钟步行样本 并通过它填充视图控制器 让我们了解下 WeeklyReport- TableViewController 类 点击 Fetch 按钮后 系统将调用 didTapFetchButton 方法
在这里 我们希望 从互联网提取服务器响应 之后 通过 serverResponse 调用 handleServerResponse 方法 让我们执行 handleServerResponse 方法 在这里 我们希望 从 serverResponse 提取每周报告 并将相应样本保存至 HealthKit 首先 我们需要从 serverResponse 提取每周报告
之后 在每周报告中循环所有样本 可以看到 我们正在循环每周报告样本 并向其返回 HKQuantitySample 在此循环中 首先需要为每个每周样本设置参数
我们设一个以米为单位的值 该数值提取自 serverHealthSample sampleType 为 sixMinuteWalkTestDistance 最后 设置开始日期和结束日期
之后 通过这些参数 初始化 HKQuantitySample
现在 我们拥有样本类型、数值 开始日期以及结束日期 元数据为“空值” 从该循环中返回的样本 需要保存至 HealthKit 现在 我们将样本保存至 HealthKit 可以看到 我们已经 使用 healthStore 保存了所有样本 之后 完成处理程序 会将新数据从 HealthKit 加载至视图控制器 让我们运行代码 查看实际场景 (构建成功)
点击 Fetch 按钮后 视图控制器 会使用每周报告中的样本进行填充
然而 当我们再次点击 Fetch 按钮 会发现重复样本保存至 HealthKit 这样不对 我们不希望 HealthKit 中包含重复数据 让我们了解下 当我们将元数据包含进 HKQuantitySample 时 会发生什么变化 创建元数据字典并加其添加进参数列表 之后 从 serverHealthSample 中 提取同步标识符 并将其添加进 HKMetadataKeySyncIdentifier 密钥 同样 我们也会从 serverHealth- Sample 提取 syncVersion 并将其添加进 HKMetadataKeySyncVersion 密钥 之后 我们将该元数据字典 添加进 HKQuantitySample 的 参数列表 让我们再次运行代码 查看实际场景
为了达到演示版本的目的 我添加了相应代码 以便在启动 app 时 删除 HealthKit 中的所有六分钟步行样本 不过请记住 在删除样本时 始终需要小心谨慎 确保如实反映用户意图
现在 点击 Fetch 每周报告显示六分钟步行样本 同时 多次点击 Fetch 并不会产生重复样本 因此 可以想见 使用 HKMetadataSyncIdentifier 和 HKMetadataSyncVersion 保存样本 能够确保 HealthKit 中不包含重复样本 现在 我们已经完成了支持该图表的数据的建模 与 HealthKit 同步外部数据 也变得不像想象中那么困难 HealthKit 会提供相应工具 帮助你在健康生态系统中 高效监测变化 同时在多个设备中保持数据一致性 我想与大家分享一些 在同步健康数据时的最佳做法 在更改用户数据时 请确保始终如实反映用户意图 即用户不会 对健康数据的更改感到惊讶 我们需要思考运行高效查询的方法 或许可以考虑组合多个查询 帮助获取并同步最少数据
最后 由于健康数据在多个设备中共存 因此 我们需要通过同步标识符和版本号 使多个设备中的数据保持一致 到这里 我们才介绍了 Apple 平台中健康系统的一小部分内容 但能做的已经很多 在使用健康数据时 需要考虑所执行操作的安全性和隐私性 在外部数据存储位置维护健康数据时 这一点尤其重要 Apple 拥有大量资源帮助你解决这一问题 如果你希望创建出 像我们今天展示的这样优质的图表可视化 可以了解 CareKit 框架 CareKit 作为开源框架 专门用于 围绕管理健康和提供护理开发 app 最后 HealthKit 还拥有其他多种功能 便于你创建丰富的健康体验 例如锻炼、临床医疗记录 以及高频数据类型 我们期待看到各位 使用所有 HealthKit 资源 创建出令人赞叹的优质 app 感谢大家的观看 希望你们在 WWDC 上有所收获
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。