概要

iOS の Widget 拡張は別プロセスで動作するため、本体アプリと直接データ共有できない。 AppGroup UserDefaults を経由してデータを共有する。本体起動時に最新データを書き込み、Widget が読み込む構造。

関連画面

同期フロー

flowchart LR App[本体アプリ起動] --> AVM[AppViewModel] AVM --> Sync[syncWidgetData] Sync --> WTip[WidgetTipData
Codable] Sync --> WCal[WidgetCalendarData
Codable] WTip --> AG[(AppGroup
UserDefaults)] WCal --> AG AG -.読込.-> SP[SmallTipWidgetProvider] AG -.読込.-> MP[MediumCalendarProvider] SP --> SW[SmallTipWidget] MP --> MW[MediumCalendarWidget]

AppGroup 設定

enum WidgetAppGroup {
    static let suiteName = "group.com.happyboy1002.DailyTips"
    static let tipDataKey = "widgetTipData"
    static let calendarDataKey = "widgetCalendarData"
}

// UserDefaults へのアクセス(共通パターン)
let store = UserDefaults(suiteName: WidgetAppGroup.suiteName) ?? .standard

同期タイミング

イベント処理
本体アプリ起動時AppViewModel が syncWidgetData() を呼出
豆知識切り替え時(日付変更)HistoryService.markAsLogin() 経由で再同期
WidgetCenter.shared.reloadAllTimelines()Widget の即時更新トリガー
Widget 自身の Timeline1時間ごと + 翌日0時に自動再取得

共有データ

WidgetTipData(Small用)

struct WidgetTipData: Codable, Sendable {
    let title: String
    let category: String
    let dateKey: String
    let updatedAt: Date
}

WidgetCalendarData(Medium用)

struct WidgetCalendarData: Codable, Sendable {
    let loginDaysThisWeek: [Bool]   // 7要素
    let loginStreak: Int
    let updatedAt: Date
}

ビジネスルール

外部連携

連携先用途
WidgetKitWidget拡張の宣言的UI実装
App Group本体・Widget間のサンドボックス共有

エラー処理

発生条件対応
AppGroup UserDefaults nilstandardへフォールバック、Logger.warning
JSON decode 失敗Widget 空表示(plain placeholder)

実装メモ

変更履歴

バージョン日付変更内容
1.02026-05-09初版作成