# 画面設計書 74-FirstRandom画面

## 概要

本ドキュメントは、Wikipedia iOSアプリの最初のランダム記事画面（FirstRandomViewController）の設計を記述したものである。

### 本画面の処理概要

FirstRandom画面は、ランダム記事機能の起点となる中間画面である。この画面自体は一時的な表示のみを行い、APIからランダム記事を取得した後、即座に実際の記事画面へ遷移する。ユーザーに対してはローディング状態として表示され、バックグラウンドでランダム記事の取得処理が実行される。

**業務上の目的・背景**：ランダム記事機能は、Wikipediaの膨大なコンテンツをユーザーに偶発的に発見させる機能として重要である。予期せぬ知識との出会いを提供することで、ユーザーの好奇心を刺激し、Wikipediaの多様性を体験させることができる。本画面は、ランダム記事取得の非同期処理中にユーザーに適切なフィードバック（ローディング状態）を提供するための中間画面として機能する。

**画面へのアクセス方法**：Explore画面のランダム記事カードやメニューからランダム機能を選択することで本画面に遷移する。画面が表示されると自動的にAPIからランダム記事を取得し、取得完了後に記事画面へ自動遷移する。

**主要な操作・処理内容**：
1. 画面表示と同時にテーマに合わせた背景色を適用
2. viewDidAppearでRandomArticleFetcherを使用してランダム記事をAPI経由で取得
3. 取得成功時はRandomArticleCoordinatorを起動して記事画面へ遷移
4. 遷移時にナビゲーションスタック内の本画面を置換（replaceLastViewControllerInNavStack: true）
5. 取得失敗時はエラーダイアログを表示

**画面遷移**：
- 遷移元：Explore画面（ランダムカード/メニュー）、各種画面からのランダム機能
- 遷移先：Article画面（ランダム記事）※ナビゲーションスタック置換

**権限による表示制御**：特になし。全ユーザーが同一の操作・表示を利用可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 60 | ランダム記事 | 主機能 | ランダムに記事を表示 |

## 画面種別

ローディング（中間画面）

## URL/ルーティング

ネイティブ画面のため、URLベースのルーティングは存在しない。ランダム機能の起動元からナビゲーションコントローラ経由でプッシュ遷移される。

## 入出力項目

| 項目名 | 型 | 入力/出力 | 説明 |
|--------|-----|----------|------|
| siteURL | URL | 入力 | Wikipedia言語サイトのベースURL |
| dataStore | MWKDataStore | 入力 | データストアインスタンス |
| theme | Theme | 入力 | 適用するテーマ |

## 表示項目

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| 背景色 | Theme.colors.paperBackground | テーマに応じた背景色のみ表示 |

## イベント仕様

### 1-画面表示（viewDidAppear）

viewDidAppearが呼ばれると、以下の処理が自動的に実行される：
1. RandomArticleFetcherインスタンスを生成
2. fetchRandomArticle(withSiteURL:)を呼び出してランダム記事を取得
3. 結果はDispatchQueue.main.asyncでメインスレッドで処理

### 2-ランダム記事取得成功

APIからランダム記事URLの取得に成功した場合：
1. RandomArticleCoordinatorを生成（replaceLastViewControllerInNavStack: true、animated: false）
2. coordinator.start()で記事画面へ遷移
3. ナビゲーションスタック内の本画面は新しい記事画面で置換される

### 3-ランダム記事取得失敗

APIからの取得に失敗した場合：
1. WMFAlertManager.sharedInstance.showErrorAlert()でエラーダイアログを表示
2. エラーがnilの場合はFetcher.unexpectedResponseErrorを表示
3. 本画面はそのまま表示される（ユーザーは戻るボタンで前画面へ戻る必要あり）

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | 本画面ではデータベース更新は発生しない |

### テーブル別更新項目詳細

本画面では直接的なデータベース更新は発生しない。ランダム記事取得後の画面遷移先でデータ更新が行われる可能性がある。

## メッセージ仕様

| メッセージID | 種別 | 表示条件 | メッセージ内容 |
|-------------|------|---------|---------------|
| エラー | エラー | API取得失敗時 | エラー内容またはunexpectedResponseError |

## 例外処理

| 例外ケース | 処理内容 |
|-----------|---------|
| APIエラー | WMFAlertManagerでエラーダイアログを表示 |
| 記事URLがnil | Fetcher.unexpectedResponseErrorをエラーとして表示 |
| ネットワーク不達 | エラーダイアログを表示、画面はそのまま |

## 備考

- UIViewControllerを直接継承し、Themeableプロトコルを実装
- hidesBottomBarWhenPushedがtrueに設定されており、タブバーは非表示
- RandomArticleCoordinatorのreplaceLastViewControllerInNavStackオプションにより、ナビゲーションスタック上で本画面が置換される
- animated: falseにより、遷移アニメーションなしで即座に記事画面が表示される
- 画面自体にはUI要素がなく、背景色のみが表示される

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、ランダム記事取得に関連するデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ArticleSummary | `WMF Framework/` | 記事サマリーのデータモデル |
| 1-2 | RandomArticleFetcher | `Wikipedia/Code/RandomArticleFetcher.swift` | ランダム記事取得のFetcher |

**読解のコツ**: RandomArticleFetcherはFetcherを継承し、feed content APIのpage/random/summaryエンドポイントを呼び出す。

#### Step 2: エントリーポイントを理解する

処理の起点となるファイル・関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | FirstRandomViewController.swift | `Wikipedia/Code/FirstRandomViewController.swift` | 本画面のメインViewController |

**主要処理フロー**:
1. **行9-16**: initでsiteURL、dataStore、themeを受け取り初期化
2. **行22-26**: viewDidLoadでテーマを適用
3. **行28-49**: viewDidAppearでランダム記事取得と遷移処理を実行

#### Step 3: API呼び出しを理解する

ランダム記事取得の実装を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RandomArticleFetcher.swift | `Wikipedia/Code/RandomArticleFetcher.swift` | ランダム記事取得ロジック |

**主要処理フロー**:
- **行5-25**: fetchRandomArticle()でfeed content APIを呼び出し
- **行6**: パスは"page/random/summary"
- **行11-24**: レスポンスからArticleSummaryをデコードし、articleURLを取得

#### Step 4: 画面遷移を理解する

記事画面への遷移処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | RandomArticleCoordinator | `Wikipedia/Code/` | ランダム記事画面遷移のコーディネーター |

**主要処理フロー**:
- **FirstRandomViewController 行42-44**: RandomArticleCoordinatorを生成し、start()を呼び出し
- replaceLastViewControllerInNavStack: trueで本画面を置換

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

```
FirstRandomViewController
    │
    ├─ init(siteURL:dataStore:theme:) [行9-16]
    │      └─ super.init()
    │
    ├─ viewDidLoad() [行22-26]
    │      └─ apply(theme:) [行51-53]
    │             └─ view.backgroundColor = theme.colors.paperBackground
    │
    └─ viewDidAppear(_:) [行28-49]
           │
           ├─ RandomArticleFetcher().fetchRandomArticle() [行31-32]
           │      │
           │      └─ configuration.feedContentAPIURLForURL() [行7]
           │             └─ session.jsonDecodableTask() [行11]
           │
           ├─ [成功時] RandomArticleCoordinator.start() [行42-44]
           │      └─ Article画面へ遷移（本画面を置換）
           │
           └─ [失敗時] WMFAlertManager.showErrorAlert() [行38]
```

### データフロー図

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

siteURL ──────────────▶ RandomArticleFetcher
                        .fetchRandomArticle()
                               │
                               ▼
                        REST API
                        /page/random/summary
                               │
                               ▼
                        ArticleSummary
                        (JSONデコード)
                               │
                               ├──[成功]──▶ articleURL
                               │                 │
                               │                 ▼
                               │     RandomArticleCoordinator
                               │           .start()
                               │                 │
                               │                 ▼
                               │          Article画面
                               │     (ナビゲーションスタック置換)
                               │
                               └──[失敗]──▶ WMFAlertManager
                                            .showErrorAlert()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| FirstRandomViewController.swift | `Wikipedia/Code/FirstRandomViewController.swift` | ソース | 本画面のメインViewController |
| RandomArticleFetcher.swift | `Wikipedia/Code/RandomArticleFetcher.swift` | ソース | ランダム記事取得のFetcher |
| RandomArticleCoordinator.swift | `Wikipedia/Code/RandomArticleCoordinator.swift` | ソース | ランダム記事画面遷移のコーディネーター |
| Fetcher.swift | `Wikipedia/Code/Fetcher.swift` | ソース | API Fetcherの基底クラス |
| ArticleSummary.swift | `WMF Framework/` | ソース | 記事サマリーデータモデル |
| WMFAlertManager.swift | `Wikipedia/Code/WMFAlertManager.swift` | ソース | アラート表示マネージャー |
| Theme.swift | `Wikipedia/Code/Theme.swift` | ソース | テーマ定義 |
