# 画面設計書 62-SplashScreen画面

## 概要

本ドキュメントは、Wikipedia iOSアプリのSplashScreen画面の設計を記載したものです。この画面はアプリ起動時に表示される初期画面で、LaunchScreen.xibと同様の外観を持ち、初期化処理やマイグレーション処理中のユーザーインタラクションをブロックします。

### 本画面の処理概要

SplashScreen画面は、アプリ起動時に最初に表示される画面であり、起動処理やデータマイグレーションが完了するまでユーザーに待機画面を提供します。

**業務上の目的・背景**：アプリ起動時には、データベースのマイグレーションやキャッシュの初期化など、時間のかかる処理が発生する場合があります。この間、ユーザーに視覚的なフィードバックを与え、アプリがフリーズしていないことを示すことで、ユーザー体験を向上させることを目的としています。また、長時間の初期化が発生した場合にはローディングアニメーションに切り替わり、ユーザーに処理中であることを明示します。

**画面へのアクセス方法**：アプリ起動時にWMFAppViewControllerから自動的に表示されます。ユーザーが意図的にアクセスする画面ではありません。

**主要な操作・処理内容**：
1. 起動画面（LaunchScreen.xib）と同じ外観のスプラッシュビューを表示
2. Wikipediaのワードマークロゴを中央に配置
3. maximumNonInteractiveTimeInterval（4秒）を超えた場合、ローディングアニメーションに遷移
4. マイグレーション処理完了後、スプラッシュ画面を非表示

**画面遷移**：
- 遷移元：アプリ起動（UIApplication起動シーケンス）
- 遷移先：Welcome画面（初回起動時）、メインタブ画面（通常起動時）

**権限による表示制御**：特になし。すべてのユーザーに対して同一の表示が行われます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 63 | 初回起動ウェルカム | 補助機能 | アプリ起動時の初期画面表示 |

## 画面種別

スプラッシュ画面 / ローディング画面

## URL/ルーティング

該当なし（アプリ起動時に自動表示）

## 入出力項目

| 項目名 | 型 | 入力/出力 | 必須 | 説明 |
|--------|-----|----------|------|------|
| theme | Theme | 入力 | 必須 | 適用するテーマ |

## 表示項目

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| splashView | 画面全体 | スプラッシュ背景画像（iPhone）またはシステム背景色（iPad） |
| wordmarkView | 中央 | Wikipediaワードマークロゴ |
| loadingAnimationViewController | 画面全体 | ローディングアニメーション（長時間待機時） |

## イベント仕様

### 1-viewDidLoad

画面がロードされた際の初期化処理。

- setupSplashView()を呼び出してスプラッシュビューを設定
- splashViewを画面全体に配置
- ワードマークロゴを中央に配置（Y軸は12ポイント下にオフセット）

### 2-triggerMigratingAnimation

マイグレーション処理開始時に外部から呼び出されるメソッド。

- maximumNonInteractiveTimeInterval（4秒）後にshowLoadingAnimation()を実行するようスケジュール
- performSelector:afterDelay:を使用

### 3-viewWillDisappear

画面が非表示になる際の処理。

- スケジュールされたshowLoadingAnimation()の呼び出しをキャンセル
- NSObject.cancelPreviousPerformRequests(withTarget:)を使用

### 4-showLoadingAnimation

ローディングアニメーションを表示するメソッド。

- loadingAnimationShowTimeに現在時刻を記録
- LoadingAnimationViewControllerを子ViewControllerとして追加
- splashViewをフェードアウト（0.3秒のクロスフェード）

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

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

この画面ではデータベース操作は発生しません。マイグレーション処理自体は別のコンポーネントが担当します。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| - | - | - | スプラッシュ画面自体にはメッセージなし |

※ローディングアニメーション画面に遷移した場合は、LoadingAnimationViewControllerの「Updating...」メッセージが表示されます。

## 例外処理

| 例外条件 | 対処 |
|----------|------|
| スプラッシュ画像リソースが見つからない | iPadの場合は背景色のみで対応 |

## 備考

- ThemeableViewControllerを継承しており、テーマ変更に対応
- iPadではsplashscreen-background画像を使用せず、systemBackground色のみを使用
- maximumNonInteractiveTimeIntervalは4秒に設定
- crossFadeAnimationDurationは0.3秒に設定
- deinitでcancelPreviousPerformRequestsを呼び出し、メモリリークを防止

---

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

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

### 推奨読解順序

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

スプラッシュ画面のUI構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SplashScreenViewController.swift | `Wikipedia/Code/SplashScreenViewController.swift` | splashView, wordmarkViewのレイアウト構造 |

**読解のコツ**: lazyプロパティで定義されたsplashViewの設定に注目してください。UIDevice.currentによるiPhone/iPadの分岐があります。

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

ViewControllerのライフサイクルメソッドを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SplashScreenViewController.swift | `Wikipedia/Code/SplashScreenViewController.swift` | viewDidLoad, viewWillDisappear |

**主要処理フロー**:
1. **18-21行目**: viewDidLoad - setupSplashView()を呼び出し
2. **23-25行目**: triggerMigratingAnimation - 4秒後にローディング表示をスケジュール
3. **27-30行目**: viewWillDisappear - スケジュールのキャンセル
4. **70-76行目**: showLoadingAnimation - ローディング画面への切り替え

#### Step 3: ローディングアニメーションを理解する

長時間待機時に表示されるローディング画面を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | LoadingAnimationViewController.swift | `Wikipedia/Code/LoadingAnimationViewController.swift` | ローディングアニメーションの実装 |

**主要処理フロー**:
- **14-24行目**: viewDidLoad - UIの初期化、「Updating...」メッセージの設定
- **30-36行目**: viewDidAppear - 衛星アニメーションの開始
- **61-85行目**: UIView拡張 - 回転アニメーションの実装

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

```
WMFAppViewController
    |
    +-- SplashScreenViewController.init()
           |
           +-- viewDidLoad()
           |      +-- setupSplashView()
           |             +-- splashView (lazy)
           |             +-- wordmarkView配置
           |
           +-- triggerMigratingAnimation() [外部呼び出し]
           |      +-- perform(#selector(showLoadingAnimation), afterDelay: 4)
           |
           +-- showLoadingAnimation() [4秒後]
           |      +-- LoadingAnimationViewController
           |      +-- UIView.animate (crossFade)
           |
           +-- viewWillDisappear()
                  +-- cancelPreviousPerformRequests()
```

### データフロー図

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

アプリ起動            --> SplashScreenViewController    --> スプラッシュ表示
                          |
                          +-- 4秒タイマー
                          |
                          v
                      showLoadingAnimation()
                          |
                          v
                      LoadingAnimationViewController --> ローディング表示
                          |
                          v
                      処理完了通知
                          |
                          v
                      画面遷移 --> Welcome画面/メインタブ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SplashScreenViewController.swift | `Wikipedia/Code/SplashScreenViewController.swift` | ソース | スプラッシュ画面のViewController |
| LoadingAnimationViewController.swift | `Wikipedia/Code/LoadingAnimationViewController.swift` | ソース | ローディングアニメーションのViewController |
| LoadingAnimationViewController.xib | `Wikipedia/Code/LoadingAnimationViewController.xib` | NIB | ローディング画面のレイアウト |
| ThemeableViewController.swift | `Wikipedia/Code/ThemeableViewController.swift` | ソース | テーマ対応の基底ViewController |
| splashscreen-wordmark | `Wikipedia/Assets.xcassets/` | 画像 | Wikipediaワードマークロゴ |
| splashscreen-background | `Wikipedia/Assets.xcassets/` | 画像 | スプラッシュ背景画像 |
