LoginSignup
8
8

More than 5 years have passed since last update.

Swift と HealthKit で栄養情報をためていく

Last updated at Posted at 2015-12-19

こんにちは、大阪のお好み焼屋です。お好み焼は最高ですが、Swiftも最高ですね。そんなわけで先日リリースした、お好み焼の栄養成分をヘルスケア(Health.app)へ送るApp、その名もレコノミーに絡めて、HealthKitをSwiftで利用する話です。

HealthKit

iOS8で新たに加わったHealthKit。いまいち盛り上がっている感じもありませんが、とりあえずデータをためておけば後でなにかいいことがあるかも・・・というわけで、iOS9で加えられたHKCorrelationTypeIdentifierFoodをつかって複数の栄養素をまとめて「メニュー単品」としてHealth.appへ送ることにします。ここではサンプルとしてうち自慢のイカ玉をつかいます。

サンプルコードと参考スクリーンショット

Simulator Screen Shot Dec 19, 2015, 23.38.18.png

主な登場Class

HealthKit
HKUnit 単位
HKQuantity
HKQuantityType 量のタイプ
HKQuantitySample モノ

「モノ」というのがよくわからないですが、とりあえずの目標がこれだと思ってください。

HKUnit, HKQuantity

順番が前後しますが、まずはHKQunatityの初期化メソッドです

init(unit unit: HKUnit!, doubleValue value: Double)

Unitは単位で、Quantityは量のことですね。unit単位にdoubleValueの値を与えてやることで量になります。100.0という数(Double)に単位グラム(HKUnit)を与えてやることで、「100グラム」という量になるわけです。

unitの初期化はいろいろなやり方が用意されています

HKUnit.percentUnit()
HKUnit(fromString: "cm")
HKUnit.gramUnitWithMetricPrefix(.Kilo)

ひとつめはいわゆるConvenience Constructor的なやつで、ここでは「%」ですが、他にも結構な数が用意されています。

2つめは単位を文字列で表す方法(ここではセンチメートル)。”m/s^2”(加速度|$m/s^2$)なんかも可能。

3つめは読んだ通り「メートル法のグラム単位をキロで」。これでキログラムになります。

let kcalUnit = HKUnit.kilocalorieUnit()
let quantity = HKQuantity(unit: kcalUnit, doubleValue: 347)

HKQuantityType, HKQuantitySample

次に量のタイプです。カロリーと一口にいっても、摂取したカロリーなのか(HKQuantityTypeIdentifierDietaryEnergyConsumed)、運動で消費したカロリーなのか(HKQuantityTypeIdentifierActiveEnergyBurned)、はたまた基礎エネルギーの消費なのか(HKQuantityTypeIdentifierBasalEnergyBurned)を、HKQuantityTypeでしっかり指定してやります。

これでようやく必要な要素がそろってHKQuantitySampleのインスタンス化ができるようになりました。

let type = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDietaryEnergyConsumed)!
let date = NSDate()
let ikatamaEnergySample = HKQuantitySample(type: type, quantity: quantity, startDate: date, endDate: date)

これでイカ玉のカロリーが完成です。あとは同じ手順で他の必要な栄養素を単位に気をつけつつインスタンス化していきます。

たとえばプロテイン(蛋白質)はこんな具合

let gramUnit = HKUnit.gramUnit()
let proteinQuantity = HKQuantity(unit: gramUnit, doubleValue: 18.9)
let proteinType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDietaryProtein)!
let ikatamaProteinSample = HKQuantitySample(type: proteinType, quantity: proteinQuantity, startDate: date, endDate: date)

HKCorrelation

コードを見ていただければ一目瞭然だとおもいます。

var itemSet = Set<HKQuantitySample>() 
itemSet.insert(ikatamaEnergySample)
//// 必要な栄養のサンプルを`insert(_)`していく
let foodType = HKCorrelationType.correlationTypeForIdentifier(HKCorrelationTypeIdentifierFood)!
let ikatama = HKCorrelation(type: foodType, startDate: date, endDate: date, objects: itemSet, metadata: metadata)

HKHealthStore

あとはストアのアベイラビリティをチェックして、ストアへのアクセスをリクエストしてやります。フレームワークが面倒をみてくれます。

guard HKHealthStore.isHealthDataAvailable() else { return }
let healthStore = HKHealthStore()

let typeSet: Set<HKSampleType> = [energyType, proteinType]
healthStore.requestAuthorizationToShareTypes(typeSet, readTypes: nil) { success, error -> Void in
  // if request is approved
  healthStore.saveObject(ikatama) { success, error in
    if success { print("DONE!!") }
  }
}

無事送れています。

Simulator Screen Shot Dec 20, 2015, 17.40.31.png

最後に

あわてて書いたのであまりSwiftっぽい話はできませんでしたが、レコノミー内ではenumを使いまくったりして、とても楽しく書くことができています。また機会があればenum+protocolの話も書ければと思っています。ありがとうございました。

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8