# 機能設計書 63-初回起動ウェルカム

## 概要

本ドキュメントは、Wikipedia iOSアプリにおける「初回起動ウェルカム」機能の設計仕様を記載する。初回起動時のウェルカム・オンボーディング画面を提供するものである。

### 本機能の処理概要

本機能は、アプリ初回起動時にユーザーにアプリの主要機能を紹介するオンボーディングフローを提供する。複数のページで構成されるウェルカム画面を通じて、探索機能、言語設定、分析データ共有についてユーザーに案内する。

**業務上の目的・背景**：新規ユーザーがアプリの価値と主要機能を理解し、スムーズに利用を開始できるようにする。また、分析データ共有の同意取得と言語設定の初期設定を促す。

**機能の利用シーン**：
- アプリ初回インストール後の起動時
- 言語設定の初期設定が必要な場合
- 分析データ共有の同意取得が必要な場合

**主要な処理内容**：
1. 導入画面（Intro）の表示：アプリの基本的な価値を紹介
2. 探索機能画面（Exploration）の表示：フィード機能を紹介
3. 言語設定画面（Languages）の表示：利用言語の選択
4. 分析データ設定画面（Analytics）の表示：データ共有の同意確認
5. ページ間のスワイプ/ボタンによるナビゲーション
6. オンボーディング完了後のメイン画面への遷移

**関連システム・外部連携**：
- UserDefaults: オンボーディング完了フラグの保存
- LanguageLinkController: 言語設定の管理

**権限による制御**：認証不要。全ての新規ユーザーに表示される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 55 | Welcome画面 | 主画面 | 初回起動時のウェルカム・オンボーディング画面 |
| 56 | WelcomePage画面 | 補助画面 | ウェルカムページのページング |
| 57 | WelcomeContainer画面 | 補助画面 | ウェルカム画面のコンテナ |
| 58 | WelcomeIntroduction画面 | 補助画面 | ウェルカム導入画面 |
| 59 | WelcomeInitial画面 | 補助画面 | 言語選択など初期設定 |
| 60 | WelcomePanel画面 | 補助画面 | 各ウェルカムステップのパネル |
| 61 | WelcomeAnimation画面 | 補助画面 | オンボーディングのアニメーション |
| 62 | SplashScreen画面 | 補助画面 | アプリ起動時の初期画面 |
| 65 | ScrollableEducationPanel画面 | 補助画面 | 各種機能説明に使用 |

## 機能種別

画面表示 / オンボーディング / ユーザー設定

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| theme | Theme | Yes | 現在のテーマ設定 | nil不可 |
| completionBlock | (() -> Void)? | No | オンボーディング完了時のコールバック | - |

### 入力データソース

- UserDefaults: オンボーディング完了状態の確認
- Storyboard: Welcome.storyboardからのUI定義読み込み

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| オンボーディング完了フラグ | Bool | オンボーディング完了状態 |
| 選択言語 | [String] | ユーザーが選択した言語リスト |
| 分析データ共有同意 | Bool | 分析データ共有の同意状態 |

### 出力先

- UserDefaults: 設定の永続化
- LanguageLinkController: 言語設定の反映

## 処理フロー

### 処理シーケンス

```
1. WMFWelcomeInitialViewControllerの表示
   └─ コンテナViewControllerとして表示
   └─ iPhone X対応のSafe Area制約を適用

2. WMFWelcomePageViewControllerの初期化
   └─ 4ページのpageControllersを構築
   └─ dataSource、delegateを設定

3. 各ページの表示
   └─ Page 1: Intro - アプリ導入
   └─ Page 2: Exploration - 探索機能紹介
   └─ Page 3: Languages - 言語選択
   └─ Page 4: Analytics - 分析データ共有

4. ページ遷移
   └─ スワイプまたはNextボタンで次ページへ
   └─ Skipボタンで全スキップ可能

5. 最終ページでの完了処理
   └─ completionBlockの実行
   └─ モーダルを閉じる
```

### フローチャート

```mermaid
flowchart TD
    A[アプリ起動] --> B{初回起動?}
    B -->|No| Z[メイン画面表示]
    B -->|Yes| C[WMFWelcomeInitialViewController]

    C --> D[WMFWelcomePageViewController]
    D --> E[Page 1: Intro]

    E --> F{ユーザー操作}
    F -->|Next/Swipe| G[Page 2: Exploration]
    F -->|Skip| Y[オンボーディング完了]

    G --> H{ユーザー操作}
    H -->|Next/Swipe| I[Page 3: Languages]
    H -->|Skip| Y

    I --> J{ユーザー操作}
    J -->|Next/Swipe| K[Page 4: Analytics]
    J -->|Skip| Y

    K --> L[Get Started タップ]
    L --> Y

    Y --> M[completionBlock実行]
    M --> N[dismiss]
    N --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-63-01 | 初回表示のみ | オンボーディングは初回起動時のみ表示 | オンボーディング未完了時 |
| BR-63-02 | スキップ許可 | どのページからでもスキップ可能 | 任意のページ表示中 |
| BR-63-03 | 最終ページでボタン非表示 | 最終ページではNext/Skip/PageControlを非表示 | 最終ページ表示時 |
| BR-63-04 | フェードインアニメーション | 2ページ目以降はフェードイン表示 | ページ遷移時 |
| BR-63-05 | ポートレート固定 | オンボーディング中は縦向き固定 | オンボーディング表示中 |

### 計算ロジック

ページ表示制御:
```swift
// 最終ページでのボタン透明度
let isLastPage = pageControllers.firstIndex(of: vc) == pageControllers.count - 1
let newAlpha: CGFloat = isLastPage ? 0.0 : 1.0
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 完了フラグ確認 | UserDefaults | SELECT | オンボーディング完了状態の取得 |
| 完了フラグ保存 | UserDefaults | UPDATE | オンボーディング完了の記録 |
| 言語設定保存 | UserDefaults | UPDATE | 選択言語の保存 |
| 分析設定保存 | UserDefaults | UPDATE | 分析データ共有設定の保存 |

### テーブル別操作詳細

#### UserDefaults

| 操作 | 項目（キー名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT/UPDATE | hasShownOnboarding | Bool | オンボーディング完了フラグ |
| UPDATE | appLanguages | [String] | 選択された言語リスト |
| UPDATE | sendUsageReports | Bool | 分析データ共有同意 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| E-63-01 | Storyboard読み込み失敗 | Welcome.storyboardが見つからない | アサーション失敗（開発時検出） |
| E-63-02 | ページ遷移失敗 | pageControllersが空 | 即座に完了処理を実行 |

### リトライ仕様

オンボーディングにリトライは不要。エラー時は完了として扱いメイン画面へ遷移。

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

設定の保存はUserDefaultsへの個別書き込みで行う。アトミック性は保証されないが、各設定は独立しているため問題なし。

## パフォーマンス要件

- ページ遷移アニメーション: 60fps維持
- フェードイン/アップアニメーション: 0.4秒、0.1秒遅延
- 起動からオンボーディング表示: 1秒以内

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

- 分析データ共有はユーザーの明示的同意を取得
- 設定情報はローカルのみに保存
- 言語設定に機密情報は含まない

## 備考

- Storyboard（Welcome.storyboard）ベースの実装
- UIPageViewControllerによるページング制御
- RTL言語対応（アラビア語等では逆方向スワイプ）
- ステータスバーは非表示

---

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

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

### 推奨読解順序

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

オンボーディングのページタイプと構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | WMFWelcomePageViewController.swift | `Wikipedia/Code/WMFWelcomePageViewController.swift` | WMFWelcomePageType enumで4種類のページを定義 |

**読解のコツ**:
- WMFWelcomePageType（intro/exploration/languages/analytics）がページ種別を表す
- WMFWelcomeNavigationDelegateプロトコルでページ遷移を通知

**主要処理フロー**:
- **3-8行目**: WMFWelcomePageType enum定義
- **10-12行目**: WMFWelcomeNavigationDelegateプロトコル定義

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

オンボーディングの起点となるViewControllerを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | WMFWelcomeInitialViewController.swift | `Wikipedia/Code/WMFWelcomeInitialViewController.swift` | コンテナVCとしての役割を理解する |

**主要処理フロー**:
- **5行目**: ThemeableViewControllerを継承
- **6行目**: completionBlockプロパティ
- **7-14行目**: prepare(for:sender:)でWMFWelcomePageViewControllerに設定を渡す
- **30-44行目**: ポートレート固定の設定

#### Step 3: ページング制御を理解する

UIPageViewControllerによるページ管理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | WMFWelcomePageViewController.swift | `Wikipedia/Code/WMFWelcomePageViewController.swift` | ページ配列とナビゲーション処理を理解する |

**主要処理フロー**:
- **77-83行目**: containerControllerForWelcomePageType()でページVC生成
- **85-92行目**: pageControllers lazy配列で4ページを管理
- **50-63行目**: showNextWelcomePage()でページ遷移
- **178-191行目**: nextButtonTapped/skipButtonTappedのハンドリング
- **224-235行目**: hideButtons()で最終ページのボタン制御

#### Step 4: 各ページのコンテナを理解する

WMFWelcomeContainerViewControllerの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | WMFWelcomeContainerViewController.swift | `Wikipedia/Code/WMFWelcomeContainerViewController.swift` | ページコンテンツとアニメーションの管理を理解する |

**主要処理フロー**:
- **22行目**: welcomePageTypeプロパティ
- **28-42行目**: viewWillAppear/viewDidAppearでフェードインアニメーション
- **44-55行目**: shouldFadeInAndUp()でアニメーション対象判定
- **75-84行目**: useBottomAlignmentIfPhone()でiPhone対応

#### Step 5: アニメーションを理解する

各ページのアニメーション実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | WMFWelcomeAnimationExtensions.swift | `Wikipedia/Code/WMFWelcomeAnimationExtensions.swift` | フェードイン/アップアニメーションを確認 |
| 5-2 | WMFWelcomeIntroductionAnimationView.swift | `Wikipedia/Code/WMFWelcomeIntroductionAnimationView.swift` | Introページのアニメーション |
| 5-3 | WMFWelcomeExplorationAnimationView.swift | `Wikipedia/Code/WMFWelcomeExplorationAnimationView.swift` | Explorationページのアニメーション |

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

```
WMFWelcomeInitialViewController
    │
    └─ prepare(for:sender:)
           │
           └─ WMFWelcomePageViewController
                  │
                  ├─ pageControllers (lazy)
                  │      │
                  │      ├─ WMFWelcomeContainerViewController (.intro)
                  │      │      ├─ WMFWelcomePanelViewController
                  │      │      └─ WMFWelcomeIntroductionAnimationView
                  │      │
                  │      ├─ WMFWelcomeContainerViewController (.exploration)
                  │      │      ├─ WMFWelcomePanelViewController
                  │      │      └─ WMFWelcomeExplorationAnimationView
                  │      │
                  │      ├─ WMFWelcomeContainerViewController (.languages)
                  │      │      ├─ WMFWelcomePanelViewController
                  │      │      └─ WMFWelcomeLanguagesAnimationView
                  │      │
                  │      └─ WMFWelcomeContainerViewController (.analytics)
                  │             ├─ WMFWelcomePanelViewController
                  │             └─ WMFWelcomeAnalyticsAnimationView
                  │
                  ├─ showNextWelcomePage()
                  │      └─ setViewControllers()
                  │
                  └─ hideButtons()
                         └─ UIView.animate()
```

### データフロー図

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

アプリ起動 ───▶ オンボーディング表示判定 ───▶ 初回起動時のみ表示
                      │
                      ▼
               WMFWelcomeInitialVC
                      │
                      ▼
               WMFWelcomePageVC
                      │
                      ▼
         ┌──────────────────────────┐
         │    ページ遷移ループ      │
         │  ┌────────────────────┐  │
         │  │ Page 1: Intro     │  │
         │  │ Page 2: Exploration│  │
         │  │ Page 3: Languages │  │
         │  │ Page 4: Analytics │  │
         │  └────────────────────┘  │
         └──────────────────────────┘
                      │
                      ▼
             completionBlock ───▶ dismiss() ───▶ メイン画面
                      │
                      ▼
               UserDefaults ───▶ オンボーディング完了フラグ保存
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| WMFWelcomeInitialViewController.swift | `Wikipedia/Code/WMFWelcomeInitialViewController.swift` | ソース | オンボーディングのコンテナVC |
| WMFWelcomePageViewController.swift | `Wikipedia/Code/WMFWelcomePageViewController.swift` | ソース | ページングを管理するPageViewController |
| WMFWelcomeContainerViewController.swift | `Wikipedia/Code/WMFWelcomeContainerViewController.swift` | ソース | 各ページのコンテナVC |
| WMFWelcomePanelViewController.swift | `Wikipedia/Code/WMFWelcomePanelViewController.swift` | ソース | パネルコンテンツの表示 |
| WMFWelcomeIntroductionViewController.swift | `Wikipedia/Code/WMFWelcomeIntroductionViewController.swift` | ソース | 導入ページのVC |
| WMFWelcomeExplorationViewController.swift | `Wikipedia/Code/WMFWelcomeExplorationViewController.swift` | ソース | 探索機能紹介ページのVC |
| WMFWelcomeLanguageTableViewController.swift | `Wikipedia/Code/WMFWelcomeLanguageTableViewController.swift` | ソース | 言語選択テーブルVC |
| WMFWelcomeAnalyticsViewController.swift | `Wikipedia/Code/WMFWelcomeAnalyticsViewController.swift` | ソース | 分析データ設定ページのVC |
| WMFWelcomeIntroductionAnimationView.swift | `Wikipedia/Code/WMFWelcomeIntroductionAnimationView.swift` | ソース | Introアニメーションビュー |
| WMFWelcomeExplorationAnimationView.swift | `Wikipedia/Code/WMFWelcomeExplorationAnimationView.swift` | ソース | Explorationアニメーションビュー |
| WMFWelcomeLanguagesAnimationView.swift | `Wikipedia/Code/WMFWelcomeLanguagesAnimationView.swift` | ソース | Languagesアニメーションビュー |
| WMFWelcomeAnalyticsAnimationView.swift | `Wikipedia/Code/WMFWelcomeAnalyticsAnimationView.swift` | ソース | Analyticsアニメーションビュー |
| WMFWelcomeAnimationExtensions.swift | `Wikipedia/Code/WMFWelcomeAnimationExtensions.swift` | ソース | アニメーション拡張 |
| UIViewController+WMFWelcomeStoryboard.swift | `Wikipedia/Code/UIViewController+WMFWelcomeStoryboard.swift` | ソース | Storyboardからのインスタンス化 |
| Welcome.storyboard | `Wikipedia/iOS Native/Welcome.storyboard` | Storyboard | オンボーディングUI定義 |
