iOS 13 / watchOS 6 HealthKit 変更点

iOS 13 で「ヘルスケア」アプリのルック＆フィールが改善され、
watchOS 6 の新機能を含む新データタイプが増えるほか、
集計関連の API などにアップデートがありました。

# 歯磨きやったよ `.toothbrushingEvent` が追加

歯磨きをしたことを表す `HKCategoryTypeIdentifier.toothbrushingEvent` を使うことができるようになりました。
単に「歯磨きした」ことを記録します。
開始時間と終了時間で「歯磨き時間」を記録するというように使います。

状態は特になく「やった」ということだけなので、`HKCategoryValue` は `.notApplicable` です。

 * [toothbrushingEvent - HKCategoryTypeIdentifier | Apple Developer Documentation](https://developer.apple.com/documentation/healthkit/hkcategorytypeidentifier/3172591-toothbrushingevent)


# 聴力テストデータタイプ `HKAudiogramSampleType` が追加

周波数と、その L と R の感度を示す 3 つの `HKQuantity` を持つ `HKAudiogramSensitivityPoint` で構成します。

```swift
let frequecy = HKQuantity(unit: HKUnit.hertz(), doubleValue: 300.0)
let dbUnit = HKUnit.decibelHearingLevel()
let left = HKQuantity(unit: dbUnit, doubleValue: 34.0)
let right = HKQuantity(unit: dbUnit, doubleValue: 27.0)
let sensitivityPoint = HKAudiogramSensitivityPoint(frequency: frequency,
                                                   leftEarSensitivity: left,
                                                   rightEarSensitivity: right)
```

これの配列を作ったら、 `HKAudiogramSample` の引数に与えて保存すれば完了です。
これで聴力テストのデータをチェックできる扱えるようになりました。

 * [audiogramSampleType() - HKObjectType | Apple Developer Documentation](https://developer.apple.com/documentation/healthkit/hkobjecttype/3042434-audiogramsampletype?)

# 騒音（耳の健康）に関するデータタイプ

聴こえている音の大きさを示すデータタイプも追加されます。
watchOS 6 から耳の健康をケアする「騒音注意」機能が追加されました。これに関連するものです。

```swift
// ヘッドホンからの音の大きさ
HKQuantityTypeIdentifier.headphoneAudioExposure
// 環境音からの音の大きさ
HKQuantityTypeIdentifier.environmentalAudioExposure
```

騒音が強くなりすぎると、 Apple Watch が警告を示し、そのタイミングで  `HKCategorySample` として `.audioExposureEvent` が保存されます。

 * [audioExposureEvent - HKCategoryTypeIdentifier | Apple Developer Documentation](https://developer.apple.com/documentation/healthkit/hkcategorytypeidentifier/3113773-audioexposureevent)


# ワークアウトタイプ (`HKWorkoutActivityType`) の追加と変更

「フィットネスゲーム」(`.fitnessGaming`) が追加。wii fit のようなアプリがターゲットになるんでしょうか。

フリスビーなどの「ディスクスポーツ」(`.discSports`)が追加。

ダンスやバレエ・ピラティスなどを基にしたトレーニングタイプ ~~`.danceInspiredTraining `~~ が廃止となり、ダンス・バレエ・ピラティスなどのタイプを使用するように変更(`.dance`, `.barre`,  `.pilates`)。

高負荷有酸素運動トレーニングをミックスしたタイプ ~~`.mixedMetabolicCardioTraining `~~ も廃止され、有酸素トレーニングをミックスしたトレーニングタイプ `.mixedCardio` または高負荷トレーニングタイプ `.highIntensityIntervalTraining` を使用するように変更となりました。

 * [HKWorkoutActivityType - HealthKit | Apple Developer Documentation](https://developer.apple.com/documentation/healthkit/hkworkoutactivitytype)

# データ表現の変更

各 `HKQuantityType` が持つプロパティ `aggregationStyle` （集計方法） が変更・拡張されました。我々が直接指定することはあまりないですが、認識をしておくと良いと思われます。

いままでは `HKStatisticsQuery` などで集計する場合のデータ表現はこの二つでした。

| Aggregation Style | 用途例 | Statistics |
|:--|:--|:--|
| `.cumulative` | 移動距離<br>消費カロリー<br>歩数 | 累計 |
| ~~`.discrete`~~ | 心拍数<br>体重<br>身長 | 平均<br>最小・最大<br>最近の値 |

このうち、 `.discrete` が deprecated になり、`.discreteArithmetic`、 `.discreteTemporallyWeighted`、`.discreteEquivalentContinuousLevel` が追加されました。

データを正確に扱うにあたって、表現方法が増えたというイメージです。

| Aggregation Style | 用途 | 備考 |
|:--|:--|:--|
| `.discreteArithmetic` | 体重<br>身長 | 算術的平均であることを明示的に表す集計方法 |
| `.discreteTemporallyWeighted` | 心拍数 | 心拍数の集計で時間加重平均を使う集計方法 (iOS 11 で追加された心拍変動に対応) |
| `.discreteTemporallyWeighted` | 騒音 | 騒音計に対応する特別な集計方法 |

 * [HKQuantityAggregationStyle - HealthKit | Apple Developer Documentation](https://developer.apple.com/documentation/healthkit/hkquantityaggregationstyle)

## 合わせて `HKQuantitySample` でもサブクラスが提供

`HKQuantityAggregationStyle` の `.cumulative` `.discrete` の変更に合わせて、 `HKQuantitySample` もサブクラスに分かれるようになりました。

つまり `HKQuantityType` の `HKQuantityAggregationStyle` に応じて、 `HKCumulativeQuantitySample` か `HKDiscreteQuantitySample` が使われます。

### `HKCumulativeQuantitySample`

時間によって蓄積されるデータに使われます。歩数や消費カロリー、歩いた距離などです。

```swift
class HKCumulativeQuantitySample : HKQuantitySample {
  var sumQuantity: HKQuantity { get }
}
```

### `HKDiscreteQuantitySample`

体温や身長、心拍数などサンプルを測ったタイミングによって変わるデータに使われます。

```swift
class HKDiscreteQuantitySample : HKQuantitySample {
  var minimumQuantity: HKQuantity { get }
  var maximumQuantity: HKQuantity { get }
  var averageQuantity: HKQuantity { get }
  var mostRecentQuantity: HKQuantity { get }
  var mostRecentQuantityDateInterval: DateInterval { get }
}
```

新しい二つの `HKQuantitySample` のサブクラスのための HKPredicateKeyPath も追加されました。
対応するプロパティをクエリするために使用します。

```swift
// HKCumulativeQuantitySample
public let HKPredicateKeyPathSum: String

// HKDiscreteQuantitySample
public let HKPredicateKeyPathMin: String
public let HKPredicateKeyPathMax: String
public let HKPredicateKeyPathAverage: String
public let HKPredicateKeyPathMostRecent: String
public let HKPredicateKeyPathMostRecentStartDate: String
public let HKPredicateKeyPathMostRecentEndDate: String
public let HKPredicateKeyPathMostRecentDuration: String
```

 * [HKCumulativeQuantitySample - HealthKit | Apple Developer Documentation](https://developer.apple.com/documentation/healthkit/hkcumulativequantitysample)
 * [HKDiscreteQuantitySample - HealthKit | Apple Developer Documentation](https://developer.apple.com/documentation/healthkit/hkdiscretequantitysample)

## ~~`HKCumulativeQuantitySeriesSample`~~

また集計のために iOS12 で導入された ~~`HKCumulativeQuantitySeriesSample`~~ は廃止となり、 `HKCumulativeQuantitySample` を使用することとなりました。


# 心拍数

### 心拍数測定の精度が上がる `HKHeartbeatSeriesSample`

心拍数について、逸脱したデータをカプセル化する `HKHeartbeatSeriesSample` も用意されました。`HKSeriesBuilder` のサブクラスを使って効率的にサンプルに心拍数やタイムスタンプが付与できるようになります。

```swift
// 追加されたクラス
class HKHeartbeatSeriesSample: HKSeriesSample
class HKHeartbeatSeriesBuilder: HKSeriesBuilder
class HKHeartbeatSeriesQuery: HKQuery
```

### 不規則な心拍 (iOS12.2+ / watchOS 5.2+)

iOS 12.2 / watchOS 5.2 から心房細動の兆候がある不規則な心拍を捉えたことを示す `HKCategoryTypeIdentifier.irregularHeartRhythmEvent` も追加されました。


# などなど

HealthKit を解説している拙著「[HealthKit Book for Beginners](https://booth.pm/ja/items/1304218)」にも本記事を追加しましてアップデート（v2.0）しましたので、購入していただいた方は PDF 版再ダウンロードおねがいしますー。（製本版は v1.0 のままです）