健康日记1:更好的HealthKit API

这将是我在我的应用程序Health Up Display上进行的一系列工作中的第一步。 我从社区中的其他开发人员那里汲取了灵感,这些开发人员已经针对自己的应用做了类似的博客。 请查看Brent Simmon的旧版Vesper Sync日记或Curtis Herbert撰写的Slopes Diaries,以获取一些示例。

启动此系列文章有一些目标。

  1. 当我通过这些事情进行推理时,一种与自己大声交谈的方法。
  2. 可能从已经解决类​​似问题的其他人那里寻求帮助。
  3. 在学习过程中,向我后面的其他人提供相同的帮助。
  4. 使用公众责任感作为脚下的火,以提供保持专注并最终发布此应用所需的动力。
  5. 在我仍将脚趾浸入博客水域时,请提供稳定的内容。

在开始之前,请先了解一下背景知识。 可惜的是,Health Up Display是我几年来一直在从事的健康和健身跟踪应用程序。 我想要一个将Health.app的数据库查看方面与iOS上Activity.app中的UI更相似的设计样式相结合的应用程序。 我还想解决我认为这两个应用程序都存在的缺点。 我喜欢将此应用程序视为这两个应用程序(如果有孩子)的产品。 我在该项目上的进展还没有达到我想要的水平,但是尽管如此,我还是取得了进展,如果您想看看的话,可以使用一个非常有用的beta。 您可以在这里注册尝试一下。

顺便说一句,我们可以继续讨论今天的日记条目。

与HealthKit进行交互的更好的API

正如我提到的,我已经在这个项目上工作了一段时间。 有些代码确实很旧。 就像旧的Swift 2.0。 另外,我只是在学习Swift,而实际上大部分只是用Swift编写的Objective-C代码。 这在一定程度上是我的错,因为我还没有熟悉这种语言,并且在那时,它的风格仍在迅速发展。 这也部分是由于这样的事实,即系统框架尚未(在许多情况下仍未真正为Swift进行过现代化)。 对于HealthKit框架尤其如此。 从好的方面来说,这是一个非常使用闭包的框架,并且在这方面非常适合Swift,但是这些闭包实际上是旧的Objective-C块。 实际上,大多数HealthKit API是使用闭包来异步处理其结果的查询。 不幸的是,在大多数情况下,这些闭包通常具有用于可选的有效查询结果和同时可选的错误的参数。 大多数Swift开发人员并不真的喜欢那样,我们也不认为它非常迅速 。 我们更喜欢使用可靠的Result类型之类的东西,以简单的switch语句清楚地区分成功还是失败。 如果您需要查看内容,请阅读这篇文章。

我的应用程序具有一些旨在为我构建这些查询的类。 它们还为我的应用程序与HealthKit交互提供了一个集中的位置和包装器。 我使用这些实例从HealthKit数据库检索运行状况统计信息,然后将它们存储在我的应用程序自己的数据缓存中,以便UI可以在启动后立即准备好您的最新统计信息。 您确实不需要每次启动应用程序时都等待查询返回。 当查询最终在以后返回较新的数据时,我将更新缓存和应用程序的UI层。 这些类充满了前面提到的并非Swifty的代码实例,而且由于我对Swift风格的了解以及对如何使用HealthKit以及与HealthKit交互的知识越来越多,现在也HealthKit 。 另外,我希望很快就可以开始使用该应用程序的Apple Watch组件,并且我还需要与该目标共享大量此类代码。 我还有一个有趣的宠物项目应用程序,名为Mowing Meter,它使用iPhone的运动协处理器芯片在修剪院子时跟踪您的步距和距离。 我目前正在将其转换为Swift,并将其也转换为“ 真正的 ”健身追踪器。 该项目也可以利用许多相同的代码。

问题域是这样。

  1. 该代码必须是可共享的。
  2. 这段代码需要更新为现代的Swift命名约定,而不像Swift中编写的Objective-C。
  3. 这种现代的Swift语法需要包含一个更好的查询返回Result类型。

解决方案

为了解决问题1,我将建立一个共享框架并将所有这些代码移到那里。 它还将提供一个很好的机会来重写它,以满足问题2和3的需要。我不会在此处编写整个过程,但是我确实觉得有一些例子是有条理的。 对于此示例,我们将更新2种方法。 在这里,它们在目前的所有荣耀,遗憾,缺乏中都得到了实现。 第一种方法创建查询以返回诸如心率,步数或活动卡路里之类的数量样本。 第二种构建查询以返回类别样本,例如停机时间或睡眠条目。 如果您不熟悉类别样本,通常可以放心地将其视为样本的几种可能状态的枚举表示。

当前代码

这是使用默认参数的最简单形式,并且为清晰起见扩展了结果处理程序。

参数类型与标签结合在一起,使这些方法易于解析并说明它们的作用。 在结果处理程序内部,我可以执行一个简单的开关来确定适当的操作过程。 我想为limitingResultsTo参数提供一个更好的标签,但是我目前为更简单的传达相同含义的东西而感到困惑。 我对这些方法的大多数调用都使用了利用默认参数的变体,这并没有什么害处,我很少看到它。 总的来说,这对我来说就像是现代Swift,我对此非常满意。 现在,我只需要像这样完成其余的框架,就可以拥有一个不错的API,并且可以很愉快地使用它。

您看到我能做得更好的任何事情还是有其他建议吗? 如果您还有其他问题或意见,请随时在Twitter或Micro.blog上向我发送反馈或想法。

Interesting Posts