# 機能設計書 7-探索フィード

## 概要

本ドキュメントは、Wikipedia iOSアプリにおける探索フィード（Explore Feed）機能の設計仕様を記述する。アプリのメイン画面として、パーソナライズされたWikipediaコンテンツをカード形式で表示する。

### 本機能の処理概要

**業務上の目的・背景**：ユーザーがアプリを開いた際に、興味のあるWikipediaコンテンツを発見できるようにする。今日の特集記事、ニュース、今日の出来事、閲覧履歴に基づく関連記事など、多様なコンテンツをカード形式で表示し、Wikipediaへのエンゲージメントを高める。

**機能の利用シーン**：
- アプリを起動した時（デフォルトタブの場合）
- 探索タブを選択した時
- Pull-to-Refreshでフィードを更新した時
- スクロールして古いコンテンツを読み込む時

**主要な処理内容**：
1. Core DataからWMFContentGroupを取得しコレクションビューに表示
2. 各カード種別に応じたUIコンポーネントの表示
3. ユーザーの設定に応じたカードのフィルタリング
4. リアルタイム更新とインクリメンタル更新
5. プロフィールボタン、検索バー、タブボタンの表示
6. カードタップによる詳細画面への遷移

**関連システム・外部連携**：
- Wikipedia Feed API（フィードコンテンツの取得）
- Core Data（WMFContentGroupの永続化）
- Notifications Center（通知センター連携）
- Profile Coordinator（プロフィール画面連携）

**権限による制御**：
- 位置情報：Places（近くの記事）カードに必要
- ログイン：Suggested Editsカードに必要（編集数50以上）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Explore画面 | 主画面 | フィードの表示、カードのインタラクション |
| 2 | ExploreFeedSettings画面 | 設定画面 | フィードカードのカスタマイズ |
| 3 | Search画面 | 連携画面 | 検索バーからの検索 |
| 5 | Article画面 | 遷移先 | 記事カードからの遷移 |

## 機能種別

表示処理 / データ取得 / ナビゲーション / 設定管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| dataStore | MWKDataStore | Yes | データストアインスタンス | nil不可 |
| theme | Theme | Yes | 適用するテーマ | 有効なThemeオブジェクト |

### フィードカード種別（WMFContentGroupKind）

| 種別 | 説明 |
|-----|------|
| featuredArticle | 今日の特集記事 |
| topRead | 今日の人気記事 |
| news | ニュース |
| onThisDay | 今日の出来事 |
| pictureOfTheDay | 今日の画像 |
| random | ランダム記事 |
| continueReading | 続きを読む |
| relatedPages | 関連記事 |
| location | 近くの記事 |
| suggestedEdits | 編集の提案 |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| フィードカード | UICollectionViewCell | 各種コンテンツカードのUI |
| ナビゲーションバー | UINavigationBar | 検索バー、プロフィールボタン |

### 出力先

- UICollectionView（メインフィード表示）
- ナビゲーションバー（検索、プロフィール）

## 処理フロー

### 処理シーケンス

```
1. ExploreViewController初期化
   └─ dataStoreを受け取り初期化

2. viewDidLoad
   └─ ExploreCardCollectionViewCellを登録
   └─ RefreshControlを有効化
   └─ NotificationCenterのオブザーバー登録

3. viewWillAppear
   └─ isGranularUpdatingEnabled = true
   └─ スクロール位置の復元
   └─ ナビゲーションバー設定

4. setupFetchedResultsController
   └─ NSFetchedResultsControllerをセットアップ
   └─ WMFContentGroupをフェッチ

5. カード表示
   └─ collectionView:cellForItemAtでセル生成
   └─ ExploreCardViewControllerを埋め込み

6. Pull-to-Refresh
   └─ refresh()でフィードソース更新
   └─ updateFeedSources()を実行
```

### フローチャート

```mermaid
flowchart TD
    A[アプリ起動] --> B[ExploreViewController表示]
    B --> C[viewDidLoad]
    C --> D[セル/オブザーバー登録]
    D --> E[viewWillAppear]
    E --> F[FetchedResultsControllerセットアップ]
    F --> G[WMFContentGroup取得]
    G --> H[コレクションビュー表示]
    H --> I{ユーザーアクション}
    I -->|Pull-to-Refresh| J[フィード更新]
    I -->|カードタップ| K[詳細画面遷移]
    I -->|スクロール| L[追加コンテンツ読み込み]
    J --> G
    K --> M[Article/News/OnThisDay等]
    L --> N[古いコンテンツ表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 言語対応 | ユーザーの設定言語に応じたコンテンツを表示 | 常時 |
| BR-002 | カード表示順 | 日付降順、種別優先度順で表示 | 常時 |
| BR-003 | Suggested Edits | 編集数50以上かつVoiceOffでない場合に表示 | 条件合致時 |
| BR-004 | 位置情報カード | 位置情報許可時のみPlacesカード表示 | 位置情報許可時 |
| BR-005 | グラニュラー更新 | 画面表示中はインクリメンタル更新有効 | viewWillAppear時 |

### カード優先度

1. Featured Article（今日の特集記事）
2. Top Read（人気記事）
3. News（ニュース）
4. On This Day（今日の出来事）
5. Continue Reading（続きを読む）
6. Related Pages（関連記事）
7. Picture of the Day（今日の画像）
8. Random（ランダム）
9. Places（近くの記事）
10. Suggested Edits（編集の提案）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| フィード取得 | WMFContentGroup | SELECT | フィードコンテンツの取得 |
| フィード更新 | WMFContentGroup | INSERT/UPDATE/DELETE | フィードコンテンツの更新 |
| 記事キャッシュ | WMFArticle | INSERT/UPDATE | 記事サマリーのキャッシュ |

### NSFetchedResultsController設定

| 項目 | 値 |
|-----|-----|
| Entity | WMFContentGroup |
| Sort Descriptors | date(DESC), contentGroupKind |
| Predicate | isVisible == true |
| Section Name Key Path | midnightUTCDateKey |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ネットワークエラー | API取得失敗 | オフラインキャッシュを表示、エラーメッセージ |
| - | データベースエラー | Core Dataエラー | エラーログ出力 |

### リトライ仕様

- Pull-to-Refreshで手動リトライ
- ネットワーク復帰時に自動更新

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

- Core Data操作はNSManagedObjectContextで管理
- バッチ更新時はperformBackgroundTaskを使用

## パフォーマンス要件

- 初期表示：2秒以内
- スクロール：60fps維持
- インクリメンタル更新：UIスレッドをブロックしない

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

- 位置情報は明示的な許可が必要
- ログイン情報はWMFAuthenticationManagerで管理

## 備考

- iPad対応でhorizontalSizeClass.regularの場合にレイアウト調整
- Year in Reviewなど季節限定コンテンツの表示に対応

---

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

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

### 推奨読解順序

#### Step 1: メインViewControllerを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ExploreViewController.swift | `Wikipedia/Code/ExploreViewController.swift` | フィードのメインViewController |

**主要コード**:
- **7行目**: クラス定義と継承プロトコル
- **67-84行目**: viewDidLoad() - セル登録、オブザーバー設定
- **97-118行目**: viewDidAppear() - 初期表示処理
- **125-131行目**: viewWillAppear() - グラニュラー更新有効化
- **162-165行目**: refresh() - Pull-to-Refresh処理
- **180-228行目**: configureNavigationBar() - ナビゲーションバー設定

#### Step 2: データ管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | WMFContentGroup | `WMF Framework/` | フィードコンテンツのCore Dataモデル |
| 2-2 | FeedContentController | `WMF Framework/` | フィードコンテンツの取得・更新 |

#### Step 3: カード表示を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ExploreCardCollectionViewCell | `Wikipedia/Code/` | カードセルのコンテナ |
| 3-2 | ExploreCardViewController | `Wikipedia/Code/` | 個別カードのViewController |

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

```
ExploreViewController
    │
    ├─ NSFetchedResultsController<WMFContentGroup>
    │      └─ Core Data (WMFContentGroup)
    │
    ├─ UICollectionView
    │      └─ ExploreCardCollectionViewCell
    │             └─ ExploreCardViewController
    │                    └─ 各種カードコンポーネント
    │
    ├─ ProfileCoordinator (プロフィール画面)
    │
    ├─ TabsOverviewCoordinator (タブ管理)
    │
    ├─ SearchViewController (検索)
    │
    └─ FeedContentController
           └─ Wikipedia Feed API
```

### データフロー図

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

Wikipedia Feed API ─────▶ FeedContentController
                               │
                               ▼
                         WMFContentGroup保存
                               │
                               ▼
                         NSFetchedResultsController
                               │
                               ▼
                         ExploreViewController
                               │
                               ▼
                         UICollectionView
                               │
                               ▼
                         [フィードカード表示]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ExploreViewController.swift | `Wikipedia/Code/` | ソース | フィードメインVC |
| ExploreCardCollectionViewCell.swift | `Wikipedia/Code/` | ソース | カードセル |
| ExploreCardViewController.swift | `Wikipedia/Code/` | ソース | カードVC |
| ExploreFeedSettingsViewController.swift | `Wikipedia/Code/` | ソース | 設定画面 |
| WMFContentGroup+CoreDataClass.swift | `WMF Framework/` | ソース | コンテンツモデル |
| FeedContentController.swift | `WMF Framework/` | ソース | フィード制御 |
| CollectionViewUpdater.swift | `Wikipedia/Code/` | ソース | 更新管理 |
| ProfileCoordinator.swift | `Wikipedia/Code/` | ソース | プロフィール連携 |
