# 機能設計書 56-その他ウィジェット

## 概要

本ドキュメントは、Wikipedia iOSアプリにおけるiOS 14以降のホーム画面ウィジェット群の設計を記述する。Picture of the Day、On This Day、Top Read、Featured Article、Searchの各ウィジェットが含まれる。

### 本機能の処理概要

**業務上の目的・背景**：iOS 14で導入されたWidgetKitフレームワークを活用し、ユーザーがホーム画面からWikipediaのコンテンツに素早くアクセスできるようにする。毎日変わるコンテンツ（今日の写真、今日は何の日、人気記事、今日の記事）を表示することで、ユーザーエンゲージメントを高める。

**機能の利用シーン**：
- Picture of the Day: 毎日の優れた写真を表示
- On This Day: 歴史上の今日の出来事を表示
- Top Read: 人気記事ランキングを表示
- Featured Article: 今日のおすすめ記事を表示
- Search: 検索入力へのクイックアクセス

**主要な処理内容**：
1. TimelineProviderによるコンテンツ取得
2. WidgetContentFetcherによるAPI呼び出し
3. 画像データの取得とキャッシュ
4. SwiftUIベースのウィジェットUI表示
5. ウィジェットタップ時のアプリ起動

**関連システム・外部連携**：
- WidgetKit Framework
- Wikimedia Feed API
- WidgetController / WidgetContentFetcher

**権限による制御**：特別な権限は不要。ウィジェット追加はユーザーの任意。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | Article画面 | 遷移先 | ウィジェットタップで記事表示 |
| - | 検索画面 | 遷移先 | 検索ウィジェットタップ |

## 機能種別

ウィジェット / データ表示 / API連携

## 入力仕様

### 入力パラメータ

TimelineProviderによる自動更新

### 入力データソース

- Wikimedia Feed API（/feed/featured）
- WidgetCache（共有コンテナ内キャッシュ）
- WidgetSettings（言語設定等）

## 出力仕様

### 出力データ

| ウィジェット | 出力内容 |
|------------|---------|
| Picture of the Day | 画像、タイトル、説明 |
| On This Day | 日付、出来事リスト |
| Top Read | 記事ランキング（1-4位） |
| Featured Article | 記事タイトル、説明、画像 |
| Search | 検索入力フィールド |

### 出力先

iOSホーム画面ウィジェット

## 処理フロー

### 処理シーケンス

```
1. ウィジェット表示/更新リクエスト
   └─ TimelineProvider.getTimeline()
2. キャッシュ確認
   └─ WidgetController.widgetCache
3a. キャッシュヒット（今日のデータあり）
   └─ キャッシュからTimelineEntry生成
3b. キャッシュミス
   └─ WidgetContentFetcher.fetchFeaturedContent()
4. 画像取得
   └─ fetchImageDataFrom()
5. Timeline生成
   └─ Timeline(entries:policy:)
6. UI更新
   └─ SwiftUIビュー描画
```

### フローチャート

```mermaid
flowchart TD
    A[ウィジェット更新] --> B[TimelineProvider]
    B --> C{スナップショット?}
    C -->|Yes| D[プレビューデータ使用]
    C -->|No| E[キャッシュ確認]
    E --> F{今日のキャッシュあり?}
    F -->|Yes| G[キャッシュ使用]
    F -->|No| H[API呼び出し]
    H --> I[データ取得]
    I --> J[キャッシュ保存]
    D --> K[Timeline生成]
    G --> K
    J --> K
    K --> L{画像あり?}
    L -->|Yes| M[画像取得]
    L -->|No| N[デフォルト表示]
    M --> O[UI描画]
    N --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-56-01 | 更新タイミング | 深夜0時以降に次回更新 | Timeline policy |
| BR-56-02 | 言語対応 | ユーザーのアプリ言語でコンテンツ取得 | 全ウィジェット |
| BR-56-03 | Featured Article言語制限 | 特定言語のみ対応 | Featured Article |
| BR-56-04 | RTL対応 | 右から左言語のレイアウト対応 | 全ウィジェット |
| BR-56-05 | サイズ対応 | Small/Medium/Largeサイズ対応 | ウィジェット種別による |

### 計算ロジック

- 更新時刻: 現在日の深夜0時以降のランダム時刻

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| キャッシュ読み込み | WidgetCache.json | READ | 共有コンテナから読み込み |
| キャッシュ保存 | WidgetCache.json | WRITE | 共有コンテナに保存 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| contentFailure | コンテンツ取得失敗 | API呼び出し失敗 | エラーメッセージ表示 |
| urlFailure | URL生成失敗 | 不正なURL | エラーメッセージ表示 |
| unsupportedLanguage | 言語未対応 | Featured Articleで未対応言語 | 言語エラーメッセージ表示 |

### リトライ仕様

Timeline policyに基づき次回更新時に再試行

## トランザクション仕様

なし（読み取りとキャッシュ書き込みのみ）

## パフォーマンス要件

- 画像サイズ最適化（POTD: 1000x1000）
- キャッシュ優先使用

## セキュリティ考慮事項

- 共有コンテナ経由のデータ共有
- HTTPS通信のみ使用

## 備考

WikipediaWidgets WidgetBundleで複数ウィジェットを管理。DEBUG時のみSearch/LockscreenSearchウィジェットが有効。

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: ウィジェット構成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Widgets.swift | `Widgets/Extension/Widgets.swift` | ウィジェットバンドル定義 |

**読解のコツ**: @mainで起点、WidgetBundleBuilderで複数ウィジェット定義

#### Step 2: 代表的なウィジェット実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | FeaturedArticleWidget.swift | `Widgets/Widgets/` | 今日の記事ウィジェット |

**主要処理フロー**:
1. **8-21行目**: Widget構造体 - 設定とProvider指定
2. **25-72行目**: TimelineEntry - エントリーデータ定義
3. **76-106行目**: TimelineProvider - データ取得
4. **110-285行目**: View - SwiftUI表示

#### Step 3: データ取得を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | WidgetController.swift | `WMF Framework/Widget/` | コントローラ |
| 3-2 | WidgetContentFetcher.swift | `WMF Framework/Widget/` | API呼び出し |

**主要処理フロー**:
- **341-395行目**: fetchFeaturedArticleContent() - 記事取得
- **26-45行目**: fetchFeaturedContent() - Feed API呼び出し

### プログラム呼び出し階層図

```
iOS WidgetKit System
    │
    └─ WikipediaWidgets (WidgetBundle)
           ├─ PictureOfTheDayWidget
           ├─ OnThisDayWidget
           ├─ TopReadWidget
           ├─ FeaturedArticleWidget
           │      ├─ FeaturedArticleProvider
           │      │      ├─ getSnapshot()
           │      │      └─ getTimeline()
           │      │             └─ WidgetController.fetchFeaturedArticleContent()
           │      │                    └─ WidgetContentFetcher.fetchFeaturedContent()
           │      │
           │      └─ FeaturedArticleView (SwiftUI)
           │
           └─ SearchWidget (DEBUG only)
```

### データフロー図

```
[入力]               [処理]                    [出力]

Widget更新 ───▶ TimelineProvider ───▶ WidgetController
リクエスト        │                        │
                 │                        ▼
                 │               WidgetContentFetcher
                 │                        │
                 │                        ▼
                 │               Feed API (/feed/featured)
                 │                        │
                 ▼                        ▼
          TimelineEntry ───▶ WidgetFeaturedContent
                 │                        │
                 ▼                        ▼
           SwiftUI View ───────────▶ ウィジェット表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Widgets.swift | `Widgets/Extension/` | ソース | ウィジェットバンドル |
| FeaturedArticleWidget.swift | `Widgets/Widgets/` | ソース | 今日の記事 |
| PictureOfTheDayWidget.swift | `Widgets/Widgets/` | ソース | 今日の写真 |
| OnThisDayWidget.swift | `Widgets/Widgets/` | ソース | 今日は何の日 |
| TopReadWidget.swift | `Widgets/Widgets/` | ソース | 人気記事 |
| SearchWidget.swift | `Widgets/Widgets/` | ソース | 検索 |
| WidgetController.swift | `WMF Framework/Widget/` | ソース | コントローラ |
| WidgetContentFetcher.swift | `WMF Framework/Widget/` | ソース | API呼び出し |
| WidgetFeaturedContent.swift | `WMF Framework/Widget/` | ソース | データモデル |
