ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
HealthKitにおける心の健康に関するAPIの詳細
HealthKitを使用して、心の健康に関する機能をアプリに取り入れる方法をご紹介します。State of Mind APIに加え、Depression Risk APIやAnxiety Risk APIなど、新しいAPIが提供されています。このセッションでは、感情を扱う科学の原則を詳細に検討し、感情を振り返ることのメリットや、State of Mind APIを使用してさまざまなタイプの気分や感情を表す方法を確認します。
関連する章
- 0:00 - Introduction
- 1:28 - Mental wellbeing APIs
- 2:13 - State of Mind API
- 8:54 - State of Mind predicates
リソース
関連ビデオ
WWDC24
WWDC20
-
ダウンロード
こんにちはヘルスケア担当 ソフトウェアエンジニアのLeahです 今日は心の健康について説明し HealthKitに新しく追加された 心の健康をサポートするAPIをご紹介します 同じくヘルスケア担当 ソフトウェアエンジニアのMattです 私のチームが開発しているアプリに これらの機能を導入する際の サポートを担当します 現代社会において心の健康はこれまで以上に 重要で関連性が高くなっています Appleは 心の健康を保つうえでは 小さな一歩が 大きな影響を与えると信じています Appleは昨年心の健康に焦点を当てた 一連の機能を発表し ユーザーが様々なデバイスで 有意義な実践に 簡単に取り組めるようになりました ヘルスケアアプリで自らの気持ちを振り返り 心の状態を記録することで 心の健康状態をトラッキングできます
心の状態の記録は Apple Watchからもできるので いつでも簡単に確認できます 心の健康状態を詳しく確認するために 不安やうつに関する標準化された質問票に ヘルスケアアプリから回答できます これらの機能がすでに 多くのユーザーに心の健康への投資を 促していることを嬉しく思っており さらに多くの人がこれらのツールの 恩恵を受けてほしいと考えています 現在 これらの体験を支えるデータ型が APIとして提供されています 本セッションでは 心の健康の背景にある 感情を扱う科学について解説し HealthKitでサンプルを 読み書きする方法も説明します
まず 用語の意味を確認しましょう GAD-7とPHQ-9は Pfizerが公開している 標準化された質問票です 世界中の医師や臨床医が 心の健康に関する スクリーニングに使用しています GAD-7は 不安のリスクを評価する 7つの質問で構成されており PHQ-9は うつのリスクを評価する 9つの質問で構成されています 今年の機能強化で GAD-7とPHQ-9の 不安とうつに関する質問の結果を 読み書きできるようになる予定です これらの新しいデータ型により 治療の有効性を調べたり 医師の診察結果を保存したりできます これらの評価は Pfizerの標準に従って 実施されることが重要です 詳細については デベロッパ向けドキュメントをご覧ください 本セッションではここから 3つ目のデータ型である State of Mindについて詳しく見ていきます State of Mindは 気分や感情を表現する手段であり 各ユーザーの積極的な振り返りが必要です 気分と感情の違いは 気持ちが生じる期間です 感情は一時的なもので 数秒から数分持続しますが 気分は長期的な感覚であり 数時間から数日 持続する場合もあります 立ち止まって振り返り 現在の感情の状態を 理解することには多くのメリットがあります 不快な感情を抱いている場合は 振り返ることでその気持ちを感じる時間を 短くすることができます 逆に 快い感情を抱いている場合には その感覚を存分に味わい 長い間楽しむことができます 快 不快 どちらでもないといった 幅広い感情を経験することは 正常で健全なことです 自分の感情を言葉で表すという実践は 感情認識能力や回復力を 長期的に高めていくことができます 自分の感情をより具体的に説明できれば より大きな臨床上のメリットが得られます Appleは これらの原則を念頭に置き 感情を扱う科学の専門家と密接に協力して State of Mind APIを設計しました その仕組みをご紹介しましょう State of Mindには 4つのパラメータがあります 1つ目のKindは心の状態の種類です 日々の気分または 一時的な感情で構成されます アプリでどちらを使うかを決める際は その気持ちのコンテキストを考慮し 対象となる気持ちが一時的なものか 長期的なものかに基づき判断します 次のValenceはどれだけ良いか悪いかの 感情の程度を自己申告で測定するものです -1から+1までの連続的なスケールで 測定されます とても気分が悪い場合は-1に近い値を選び 気分が非常に良い場合は +1に近い値を選びます 0に近いニュートラルな値は 様々な気持ちに適しています Labelsは心の状態を表現するラベルで 情熱を感じている 圧倒されている 安堵しているなどから選択します 非常に多くの選択肢が用意されており 心の状態を十分に表すうえで必要なだけ いくつでも指定できます
最後のAssociationsは 感情の原因を表します 家族 アイデンティティ 仕事などから選択します Labelsと同様に 多数の選択肢があり いくつでも指定できます State of Mindは 自身の感情の状態を 振り返るための方法として開発され 臨床上の真のメリットを提供することを 目的としています ただし そのユースケースは 心の健康のみに重点を置いた アプリに限定されません State of Mindは様々なアプリで使用でき 落ち着いて自己を振り返るための あらゆる用途において有用です 短いシンプルなやり取りを通して 振り返りとマインドフルネスを あらゆる体験に組み込むことができます あなたならこのAPIをどのように チームのアプリで使いますか? State of Mindについて もう少し詳しく学べば 新しいAPIを使って カレンダーイベントに 気持ちを関連づけられると思います 背景情報として 私は時間の使い方を 視覚化するアプリに取り組んでいます その取り組みをお見せしましょう 現在 アプリはオフィス ソーシャルメディア ワークアウトの すべてのカレンダーイベントを 表示しています このアプリは時間の使い方を視覚化して インサイトを提供します 新しいState of Mind APIを使って さらに高度な機能を提供したいと思います 具体的には 心の状態を追加して イベントをどう感じたかを 表現できるようにします この機能を作成してみましょう まず 標準のHealthKit認証フローにより State of Mindのサンプルを 読み書きするアクセス権をリクエストします 健康データはすべて プライバシーと安全性が確保されます また認証により ユーザー管理と 共有するデータの指定ができます 認証の詳細については WWDC20の「Getting started with HealthKit」をご覧ください 次はアプリの体験です 気分や感情は様々な方法で表現できます 個人的には 絵文字を使うと 気持ちを楽しく 手軽に表現できると思うので HealthKitに保存できる State of Mindのサンプルに対応する 絵文字のセットを使います まず 5つの絵文字を選びます それぞれがState of Mindのラベルに 対応します 次に考えるのは 各々をState of Mindのサンプルに どう反映するかです
EmojiTypeという 新しい列挙型を作ってみましょう これには サンプルの作成に使う 各絵文字が含まれます 次に カレンダーイベントとEmojiTypeの State of Mindのサンプルを作成する 関数を作ります 最近のイベントのサンプルを 作成しているので 気持ちの種類を表すkindには momentaryEmotionを使います 次に 快不快の程度を表す valenceの値が必要です 新しいvalenceプロパティを持つように 作成したemojiType列挙型を修正します これにより各絵文字が Doubleで表される valenceにマッピングされます
Leahが説明した State of Mindのラベルを確認した後 emojiTypeに labelという別のプロパティを作成し 各絵文字用に選んだ State of Mindのラベルを定義します 使用するassociationは イベントカレンダーに基づき イベントから推測することもできます 例えば オフィスカレンダーは 仕事のassociationにマッピングされます これで HKStateOfMindイニシャライザによる サンプル作成に必要なものが すべて揃いました サンプルの保存は healthStoreで 既存のsaveメソッドを使うだけで済みます
以上です チームの スタンドアップイベントにも間に合って とても幸せな気持ちです その気持ちをアプリに保存してみましょう カレンダーイベントをタップすると 新しい絵文字ピッカーが表示されるので 絵文字を選択し サンプルをHealthKitに保存します 簡単ですね アプリではイベントが終わるたびに 気持ちを確認するように促します これにより 感情認識能力や 回復力が身につきます 誰でも簡単に心の健康状態を把握でき 臨床上の真のメリットが得られます - さて 他には何ができますか? - 今からお見せします
State of Mindのログのメリットは 気持ちを振り返る きっかけになることだけではありません 過去の気持ちを振り返ると 非常に多くの情報が得られます 傾向を把握できるかもしれません 十分な睡眠がとれていないと 気分が優れなかったり 積極的に運動すると 気分が明るくなったりという傾向です ヘルスケアアプリでは 時間の経過に伴う 気持ちの変化を確認できます また 友人 健康 趣味といった生活の 各領域との関連に着目して比較ができます エクササイズ時間 意識的な時間 睡眠時間など 他のデータ型との比較も表示できます 自分の気持ちを より大局的な観点から理解できると 生活を大きく変えることにつながります 心身両方の健康に より気を配れるようになります State of Mindを使うと 気持ちに基づいて コンテキストの中で人生の出来事を把握し 各ユーザー固有の状況を反映した インサイトを得られます HealthKitに 4つの新しい述語が導入されます Kindによるクエリを実行して 感情と気分を区別でき 各時点や日を単位として 変化をハイライトできます Valenceの述語を使うと 快不快の 程度に基づいてサンプルを取得できます 特定のラベルを持つ State of Mindのサンプルを検索でき 落ち着く ストレスを感じるなどの感情が どのような時に生じるか把握できます Associationsの述語を使うと デートや趣味など 生活の特定の分野に基づき 気持ちに対するクエリを実行できます これらの述語を使うと 必要な情報をすばやく得ることができ 説得力のあるインサイトの 提供に注力できます 最高に良い気持ちになる瞬間を ハイライトしたり 困難な状況にある時に サポートのための リソースを提供したりできます これらを使って何ができますか? その質問を待っていました クエリです 現時点でも アプリで時間の使い方に関する インサイトが提供されています State of Mindの特定のサンプルに対し クエリを実行して より詳細なインサイトを得る方法を 説明します タブには その週の ワークライフバランスのスコアが表示され また 最も有意義なイベントも ハイライトされます ワークライフバランスは 日中のイベントの予定と自由時間の 割合を測定して計算します カレンダーの大部分が ミーティングの予定で埋まっている場合 ワークライフバランスは良くありません ワークライフバランスの指標は有益ですが 人生の大局的な理解に役立つ 視点の一つに過ぎません 例えば 忙しい日ほど 充実感が得られることもありますし イベントが 楽しいアクティビティであることもあります この指標を向上させる方法の一つが その日の気持ちを考慮に入れることです それを測定するには 各日について クエリでassociationのある State of Mindのサンプルを取得します まず アプリのカレンダーイベントに関連する associationのある 特定の日付範囲のサンプルを すべて取得するクエリ述語を作成します それを新しい stateOfMindPredicateメソッドに渡して 述語に一致するサンプルを見つけます 次に HealthKitクエリを作成して 結果を取得します その結果を使って これらのサンプルのvalenceプロパティを すべて変換して結合し 気持ちの指標を表す割合として valenceの平均を求めます このCalendar Qualityという新しい指標を タブに追加することで 1週間の気持ちを ハイライトできるようになります それだけではありません このアプリは もう1つのインサイトとして その週で最も有意義なイベントを提示します 現在この指標は その週で最も長い カレンダーイベントをクエリして計算しています よく考えてみると 時間の長さでは そのイベントの意義を 実際に確認することはできません 修正しましょう 代わりにHealthKitで 絵文字ピッカーのいずれかのラベル 例えばHappyを取得するクエリを実行します ここではassociationと labelの両方の述語を使って 目的のサンプルの型を正確に特定します 次に valenceが最も高いサンプルを特定し その期間で一番近い カレンダーイベントを見つけます
これでOKです Happyラベルに加え State of Mindの複数のラベルについて この手順を行い 1週間の様々なインサイトを 示すことができます 確実に良くなりますね State of Mindのデータを使って アプリを強化し 気持ちに基づく 新たなインサイトを示すことで 真にパーソナライズされた体験を 実現できます まだ始まったばかりです 「Get started with HealthKit in visionOS」では チームメイトのZachとSirindaが 私たちのアプリをVision Proに導入します visionOSの空間キャンバスを活用した体験を HealthKitを使って 構築する方法を説明します Vision Proに合わせて アプリの動作を調整する方法も説明します これには ゲストユーザーの扱いの サポートも含まれます ただ 現時点で アプリの状態はだいぶ向上したと思います - あなたはどう思いますか? - 素晴らしいです 1週間の振り返りとして 時間の使い方に加え気持ちを考慮するのは 良いアイデアですね すべてのデバイスで 心の健康をサポートするために 他にも新機能が追加されています 「Enhanced suggestions for your journaling app」では 同僚のReneが ジャーナル記録の パーソナライズされたState of Mindの 提案機能を活用する方法を説明します 本ビデオでは多くの内容を説明しました State of Mindは 感情を扱う科学の原則に基づいており 臨床上の真のメリットをもたらします サンプルの各プロパティは ユーザーの気持ちに関する 重要な情報を提供します これらの新しいAPIにより 効果的な体験を簡単に創出できます State of Mindは瞑想や日記 その他のマインドフルネスの実践など 心の健康の向上に役立つ有用なツールです 人は生活のあらゆる場面で 様々な気持ちを体験するので アプリを強化してマインドフルネスを あらゆる体験に取り入れることができます State of Mindをアプリに導入すると 説得力のあるインサイトを 効果的に提供できます 例えば 感情の回復力を向上させたり ポジティブな瞬間を称えたり 生活の中にある重要なパターンを 認識する支援ができます 最後に 留意点をいくつか挙げます 心の健康は生活のあらゆる場面で重要です アプリでの新しいAPIの 活用方法を検討してください フィードバックアシスタントを使って ご意見をお聞かせください ヘルスケアと心の健康について詳しくは 先ほどご紹介したセッションもご覧ください State of Mindを 既存のアプリに組み込むにしても 新しいアプリを作るインスピレーションを 得るにしても みなさんがどのようなものを生み出すのか とても楽しみです
-
-
5:37 - Request authorization to read and write State of Mind HealthKit samples
// Request authorization to read and write State of Mind HealthKit samples import HealthKitUI func healthDataAccessRequest( store: HKHealthStore, shareTypes: Set<HKSampleType>, readTypes: Set<HKObjectType>? = nil, trigger: some Equatable, completion: @escaping (Result<Bool, any Error>) -> Void ) -> some View
-
6:26 - EmojiType
// EmojiType enum EmojiType: CaseIterable { case angry case sad case indifferent case satisfied case happy var emoji: String { switch self { case .angry: return "😡" case .sad: return "😢" case .indifferent: return "😐" case .satisfied: return "😌" case .happy: return "😊" } } }
-
6:32 - Create State of Mind sample for an event and emoji selection
/// Create State of Mind sample for an event and emoji selection func createSample(for event: EventModel, emojiType: EmojiType) -> HKStateOfMind { let kind: HKStateOfMind.Kind = .momentaryEmotion let valence: Double = emojiType.valence let label = emojiType.label let association = event.association return HKStateOfMind(date: event.endDate, kind: kind, valence: valence, labels: [label], associations: [association]) }
-
7:21 - Save State of Mind sample from emoji choice
// Save State of Mind sample from emoji choice func save(sample: HKSample, healthStore: HKHealthStore) async { do { try await healthStore.save(sample) } catch { // Handle error here. } }
-
10:34 - Query State of Mind samples
// Query State of Mind samples let datePredicate: NSPredicate = { ... } let associationsPredicate = NSCompoundPredicate ( orPredicateWithSubpredicates: associations.map { HKQuery.predicateForStatesOfMind(with: $0) } ) let compoundPredicate = NSCompoundPredicate( andPredicateWithSubpredicates: [datePredicate, associationsPredicate] ) let state0fMindPredicate = HKSamplePredicate.stateOfMind(compoundPredicate)
-
10:49 - Query State of Mind samples
// Query State of Mind samples let datePredicate: NSPredicate = { ... } let associationsPredicate = NSCompoundPredicate ( orPredicateWithSubpredicates: associations.map { HKQuery.predicateForStatesOfMind(with: $0) } ) let compoundPredicate = NSCompoundPredicate( andPredicateWithSubpredicates: [datePredicate, associationsPredicate] ) let stateOfMindPredicate = HKSamplePredicate.stateOfMind(compoundPredicate) let descriptor = HKSampleQueryDescriptor(predicates: [stateOfMindPredicate], sortDescriptors: []) var results: [HKStateOfMind] = [] do { // Launch the query and wait for the results. results = try await descriptor.result(for: healthStore) } catch { // Handle error here. }
-
10:54 - Query State of Mind samples (continued)
// Adjust each valence value to be from a range of 0.0 to 2.0. let adjustedValenceResults = results.map { $0.valence + 1.0 } // Calculate average valence. let totalAdjustedValence = adjustedValenceResults.reduce (0.0, +) let averageAdjustedValence = totalAdjustedValence / Double(results.count) // Convert valence to percentage. let adjustedValenceAsPercent = Int(100.0 * (averageAdjustedValence / 2.0))
-
11:33 - Query for relevant State of Mind samples with a specific label
// Query for relevant State of Mind samples with a specific label let label: HKStateOfMind.Label = .happy // Configure the query let datePredicate = HKQuery.predicateForSamples(withStart: dateInterval.start, end: dateInterval.end) let associationPredicate = HKQuery.predicateForStatesOfMind(with: association) let labelPredicate = HKQuery.predicateForStates0fMind(with: label) let compoundPredicate = NSCompoundPredicate( andPredicateWithSubpredicates: [datePredicate, associationPredicate, labelPredicate] ) let stateOfMindPredicate = HKSamplePredicate.stateOfMind(compoundPredicate) let descriptor = HKAnchoredObjectQueryDescriptor(predicates: [state0fMindPredicate], anchor: nil) // Fetch the results let results = descriptor.results(for: healthStore) let samples: [HKStateOfMind] = try await results.reduce([]) { $1.addedSamples }
-
11:45 - Process State of Mind sample data
// Process State of Mind sample data let happiestSample = samples.max { $0.valence < $1. valence } let happiestEvent: EventModel? = findClosestEvent(startDate: happiestSample?.startDate, endDate: happiestSample?.endDate)
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。