WWDC Quick Look 💓 By SwiftGGTeam
Enhanced suggestions for your journaling app

Enhanced suggestions for your journaling app

元の動画を見る

ハイライト

iOS 18 では Journaling Suggestions API に 4 つの新アセットタイプが追加:State of Mind(心理状態)、Motion Activity のランニングタイプ、Generic Media(サードパーティメディア)、Reflection Prompts(振り返りプロンプト)。日記 App は大幅なコード変更なしで、より豊富な執筆素材を取得できます。


主要内容

日記 App が直面する中核的な問題:ユーザーが App を開いても何を書けばいいかわからない。Journaling Suggestions API は iOS 17.2 でこの問題への解決を試みました——iOS がユーザーの生活の写真、運動、場所などのイベントを自動感知し、日記執筆の起点として提案します。リリースから数か月で多数の App がこの API を採用しました。

iOS 18 では提案コンテンツがより豊かになります。これまで日記 App が取得できた素材は Apple エコシステム内に限られていました:Apple Music の曲、Apple Podcasts のポッドキャスト、iPhone が検出した散歩。しかしユーザーの生活は Apple App だけでは完結しません——サードパーティ App で音楽やポッドキャストを聴き、Health で感情を記録し、感知データではなく執筆プロンプトが必要な場合もあります。iOS 18 の 4 つの更新はまさにこれらのギャップを埋めます。

第一に State of Mind。Health App で記録された感情データが日記提案の一部として表示可能。第二に Motion Activity にランニングと混合ウォーク/ランの 2 種類を追加。Apple Watch がなくてもランニングするユーザーをカバー。第三に Generic Media で非 Apple App で消費した音楽とポッドキャストをサポート。第四に Reflection Prompts で、以前 Apple Journal 独占だった振り返りプロンプトをすべての開発者に開放。横画面サポートも自動適用され、iOS 18 の Journaling Suggestions は覆盖面の広い更新です。


詳細

横画面サポート(01:59

iOS 17.2 の Journaling Suggestions ピッカーは縦画面固定でした。iOS 18 から、ピッカーは App の縦横設定に自動追従。中央の確認画面(ユーザーが共有内容をレビューする場所)も、より広い画面を活用して大きなアセットプレビューを表示。開発者の変更は不要——App が横画面をサポートすればピッカーも自動適応。

State of Mind アセット(02:50

State of Mind は iOS 17 で Health App に導入された機能で、2 種類の感情サンプルを記録可能:Momentary Emotions(今この瞬間の気持ち)と Daily Moods(1 日全体の気分)。各サンプルには 3 次元のデータが含まれます:

  • Valence:効価。感情のポジティブ/ネガティブ度
  • Labels:ラベル。「穏やか」「満足」など感情の具体的タイプ
  • Associations:関連要因。「家族」「仕事」「フィットネス」など何がこの気持ちをもたらしたか

State of Mind 提案は単独で表示されることも、既存の外出、活動、在宅などの提案に付加されることもあります。新アセットタイプは JournalingSuggestion.StateOfMind で、HKStateOfMind サンプル、画像 URL、明暗テーマカラー、タイムスタンプを含みます。セッションで説明されたコードパターン:

// suggestion から State of Mind アセットを取り出す
let stateOfMindItems = suggestion.content.compactMap { $0 as? JournalingSuggestion.StateOfMind }

for item in stateOfMindItems {
// AsyncImage でアセットアイコンを表示
    AsyncImage(url: item.icon)
// カスタム関数で価数を絵文字に変換
    Text(getEmotionEmoji(valence: item.stateOfMind.valence))
}

func getEmotionEmoji(valence: Double) -> String {
    if valence > 0 { return "😊" }
    else if valence < 0 { return "😔" }
    else { return "😐" }
}

キーポイント:

  • compactMap { $0 as? JournalingSuggestion.StateOfMind } で提案コンテンツから State of Mind タイプのアセットをフィルタ
  • item.icon はアセットアイコンの URL。AsyncImage に直接使用可能
  • item.stateOfMind.valence で効価にアクセス。正値はポジティブ、負値はネガティブ
  • labelsassociations を活用して、より表現力のある感情執筆体験を構築

Motion Activity の更新(07:20

iOS 17.2 の Motion Activity は散歩検出のみ(iPhone ベース、Apple Watch 不要)。iOS 18 でランニング(Run)と混合ウォーク/ラン(Mixed Walk/Run)を追加。アセットタイプは引き続き JournalingSuggestion.MotionActivity で、新フィールド movementType が運動タイプを識別。各運動タイプに対応アイコン付き。

// suggestion から Motion Activity アセットを取り出す
let motionItems = suggestion.content.compactMap { $0 as? JournalingSuggestion.MotionActivity }

for item in motionItems {
    AsyncImage(url: item.icon)
    Text(getMotionActivityLabel(type: item.movementType))
}

func getMotionActivityLabel(type: MovementType) -> String {
    switch type {
case .running: return "ランニング"
case .walking: return "ウォーキング"
case .mixedWalkRun: return "ウォーキング+ランニング"
default: return "運動"
    }
}

キーポイント:

  • movementType は新フィールド。散歩、ランニング、混合運動を区別
  • この提案は iPhone センサーベース。Apple Watch 不要
  • 運動提案は引き続き写真や音楽と組み合わせて表示可能

Generic Media(09:17

iOS 17.2 の Song と Podcasts アセットは Apple Music と Apple Podcasts のみ。iOS 18 で JournalingSuggestion.GenericMedia を追加。サードパーティ App で消費した音楽とポッドキャストをサポート。アセットには title、artist、album、appIcon、タイムスタンプを含む。サードパーティメディア App は Now Playing API でデータを寄付し、不参加も選択可能。

// suggestion から Generic Media アセットを取り出す
let mediaItems = suggestion.content.compactMap { $0 as? JournalingSuggestion.GenericMedia }

for item in mediaItems {
    AsyncImage(url: item.appIcon)
    if let title = item.title { Text(title) }
    if let artist = item.artist { Text(artist) }
    if let album = item.album { Text(album) }
}

キーポイント:

  • compactMap { $0 as? JournalingSuggestion.GenericMedia } でサードパーティメディアアセットをフィルタ
  • appIcon はメディアを再生している App のアイコン。アルバムアートではない
  • titleartistalbum は寄付 App のデータに依存し存在保証なし。使用前に必ず nil チェック
  • 設定の Media トグルで制御

Reflection Prompts(11:39

振り返りプロンプトは、感謝、親切、目標などのテーマに関する一般的な執筆ガイド。感知ベースの提案と異なり、汎用的で時間制限なし——ユーザーはいつでも同じプロンプトに戻れる。デフォルトで有効。設定に独立した Reflection Prompts トグルあり。ユーザーは提案ピッカーでボタンをタップして異なるプロンプトに切り替え可能。

アセットタイプは JournalingSuggestion.Reflection。プロンプトテキスト(prompt)と背景色(backgroundColor)を含む。

// suggestion から Reflection アセットを取り出す
let reflectionItems = suggestion.content.compactMap { $0 as? JournalingSuggestion.Reflection }

for item in reflectionItems {
    item.backgroundColor.map { color in
        Text(item.prompt)
            .foregroundStyle(getForegroundColor(for: color))
            .background(color)
    }
}

func getForegroundColor(for backgroundColor: Color) -> Color {
// 背景の明るさに応じて前景色を選択
    backgroundColor.isLight ? .black : .white
}

キーポイント:

  • item.prompt はユーザーが選択したプロンプトテキスト文字列
  • item.backgroundColor は提案ピッカーでこのプロンプトを表示するときの色。App 内でも視覚的一貫性を保つために使用
  • 前景色は背景の明度から計算し、文字の可読性を確保
  • 振り返りプロンプトはデフォルトで有効。ユーザーの手動有効化不要

統合ガイダンス(13:54

App が新アセットタイプを採用しない場合、completion block が返す新コンテンツは無視され、ユーザーが混乱します。フォールバックアセットタイプ(UIImageImage)もサポートし、すべてのフィールドを処理しなくても基本的な表示能力を確保。すべてのデータ共有はユーザーが制御:ユーザーが提案に含めるコンテンツ、送信する提案、含めるアセットを選択。


重要ポイント

  • やること:日記 App に State of Mind アセットを統合し、感情データを執筆コンテキストとして表示。理由:感情と日記執筆は自然に関連。Health App の感情データが執筆のハードルを下げる。始め方:既存の compactMap フィルタチェーンに JournalingSuggestion.StateOfMind を追加。valencelabelsassociations で感情表示 UI を構築。

  • やること:Reflection Prompts を毎日の執筆ガイド機能として統合。理由:統合ハードルが最も低い(文字列 1 つと色 1 つ)が、「何を書けばいいかわからない」という中核的痛点に直接対応。始め方JournalingSuggestion.Reflection をフィルタ。prompt でガイドテキストを表示、backgroundColor で視覚的一貫性を維持。

  • やること:Generic Media アセットをサポートし、サードパーティ App で聴いた音楽とポッドキャストを記録。理由:多くのユーザーのメインプレイヤーは Apple Music ではない。以前はこのコンテンツが日記で完全に不可視だった。始め方JournalingSuggestion.GenericMedia をフィルタ。appIcon でソース App を区別。titleartistalbum は空の可能性あり、必ず nil チェック。

  • やること:Motion Activity の新運動タイプ用 UI を追加。理由:ランナーは膨大なユーザー層。この検出は iPhone ベースで Apple Watch 不要。時計なしでよく運動するユーザーをカバー。始め方movementType フィールドを確認。.running.mixedWalkRun に対応するアイコンと文案を提供。


関連セッション

コメント

GitHub Issues · utterances