# 機能設計書 37-通知設定

## 概要

本ドキュメントは、Wikipedia iOSアプリにおける通知設定機能について、その設計仕様を詳細に記載したものである。

### 本機能の処理概要

通知設定機能は、プッシュ通知の有効化/無効化およびシステム設定への誘導を管理する機能である。

**業務上の目的・背景**：ユーザーがプッシュ通知を自分の好みに合わせて制御できるようにすることで、通知による不快感を軽減しつつ、必要な情報をタイムリーに受け取れるようにする。

**機能の利用シーン**：
- プッシュ通知を有効化したい場合
- プッシュ通知を無効化したい場合
- 通知許可状態を確認したい場合

**主要な処理内容**：
1. 通知許可状態の確認と表示
2. プッシュ通知の有効化リクエスト
3. システム設定画面への誘導
4. Echo通知サービスへの購読/購読解除
5. デバイストークンの登録待機

**関連システム・外部連携**：
- iOSシステム設定
- WMFNotificationsController
- WMFAuthenticationManager

**権限による制御**：ログイン済みユーザーのみ設定変更可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | NotificationSettingsViewController | 主画面 | 通知設定の表示と変更 |

## 機能種別

設定管理 / システム連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| isEnabled | Bool | Yes | 通知を有効にするかどうか | - |

### 入力データソース

- 画面入力：スイッチコントロールのオン/オフ
- システム入力：iOSの通知許可状態

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 設定画面セクション | [NotificationSettingsSection] | 表示するセクションと項目 |

### 出力先

- 画面表示（設定項目のリスト）

## 処理フロー

### 処理シーケンス

```
1. 設定画面を表示
   └─ NotificationSettingsViewController
2. ログイン状態を確認
   └─ authManager.isLoggedIn
3. 通知許可状態を確認
   └─ notificationsController.notificationPermissionsStatus()
4. 状態に応じたセクションを表示
   └─ sectionsForPermissionsNotDetermined() / sectionsForPermissionsDenied() / sectionsForPermissionsAllowed()
5. ユーザー操作に応じて処理
   └─ スイッチオン: requestPermissionsIfNeededAndRegisterDeviceToken()
   └─ ボタンタップ: システム設定へ遷移
```

### フローチャート

```mermaid
flowchart TD
    A[設定画面表示] --> B{ログイン状態}
    B -->|未ログイン| C[ログイン促進表示]
    B -->|ログイン済み| D{通知許可状態}
    D -->|未決定| E[有効化スイッチ表示]
    D -->|拒否| F[設定画面誘導ボタン表示]
    D -->|許可済み| G{デバイストークン?}
    G -->|取得中| H[待機中メッセージ表示]
    G -->|取得済み| I[有効表示]
    G -->|取得失敗| J[エラーメッセージ表示]
    E --> K[スイッチオン]
    K --> L[許可リクエスト]
    L --> M{許可された?}
    M -->|Yes| N[Echo購読]
    M -->|No| F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-37-01 | ログイン必須 | 未ログイン時はログイン画面へ誘導 | 常時 |
| BR-37-02 | 許可状態表示 | iOS許可状態に応じて異なるUIを表示 | 常時 |
| BR-37-03 | システム設定連携 | 許可拒否時はシステム設定への誘導のみ | 許可拒否時 |
| BR-37-04 | トークン待機 | デバイストークン取得中は待機表示 | トークン取得中 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| なし | - | - | - |

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

設定画面自体はデータベース操作を行わない。WMFNotificationsControllerを介してUserDefaultsに保存。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 許可リクエストエラー | 許可リクエスト失敗時 | wmf_showAlertWithError() |
| - | 購読エラー | Echo購読失敗時 | wmf_showAlertWithError() |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

特になし

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

ログイン状態の確認を行い、未認証ユーザーには設定変更を許可しない。

## 備考

- アプリがアクティブになったときにセクションを更新（didBecomeActiveNotification）
- 複数の許可状態に対応したUI切り替え

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | NotificationSettingsViewController.swift | `Wikipedia/Code/NotificationSettingsViewController.swift` | 設定項目のモデル定義 |

**主要処理フロー**:
- **5-27行目**: NotificationSettingsItem, NotificationSettingsSwitchItem, NotificationSettingsButtonItem, NotificationSettingsInfoItem, NotificationSettingsSectionの定義

#### Step 2: ビューコントローラーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | NotificationSettingsViewController.swift | `Wikipedia/Code/NotificationSettingsViewController.swift` | 画面制御ロジック |

**主要処理フロー**:
- **48-52行目**: 初期化とdeviceTokenDelegate設定
- **59-66行目**: viewDidLoad()でテーブル設定とNotificationCenter購読
- **74-77行目**: viewWillAppear()でセクション更新
- **177-218行目**: updateSections()で許可状態に応じたUI切り替え

#### Step 3: セクション生成ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | NotificationSettingsViewController.swift | `Wikipedia/Code/NotificationSettingsViewController.swift` | 状態別セクション生成 |

**主要処理フロー**:
- **79-95行目**: sectionsForPermissionsNotDetermined() - 未決定時のUI
- **134-142行目**: sectionsForNotLoggedIn() - 未ログイン時のUI
- **144-152行目**: sectionsForPermissionsDenied() - 拒否時のUI
- **167-175行目**: sectionsForPermissionsAllowed() - 許可時のUI

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

```
NotificationSettingsViewController
    │
    ├─ viewDidLoad()
    │      └─ NotificationCenter.addObserver(didBecomeActiveNotification)
    │
    ├─ viewWillAppear()
    │      └─ updateSections()
    │
    ├─ updateSections()
    │      ├─ authManager.isLoggedIn チェック
    │      └─ notificationsController.notificationPermissionsStatus()
    │              ├─ .denied → sectionsForPermissionsDenied()
    │              ├─ .notDetermined → sectionsForPermissionsNotDetermined()
    │              └─ .authorized → sectionsForPermissionsAllowed()
    │
    └─ requestPermissionsIfNeededAndRegisterDeviceToken()
           ├─ notificationsController.requestPermissionsIfNecessary()
           └─ notificationsController.subscribeToEchoNotifications()
```

### データフロー図

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

ログイン状態 ────────────────▶ NotificationSettingsViewController ▶ セクション配列
                             ┌─────────────────────────────┐
通知許可状態 ────────────────▶│  状態判定                     │  ▶ UI表示
                             │  ・未ログイン？              │
                             │  ・許可済み？                │
デバイストークン ───────────▶│  ・拒否？                    │  ▶ テーブル更新
                             │  ・未決定？                  │
                             └─────────────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| NotificationSettingsViewController.swift | `Wikipedia/Code/NotificationSettingsViewController.swift` | ソース | 通知設定画面 |
| WMFNotificationsController.swift | `WMF Framework/Notifications/WMFNotificationsController.swift` | ソース | 通知許可とデバイストークン管理 |
| WMFAuthenticationManager.swift | `WMF Framework/Authentication/WMFAuthenticationManager.swift` | ソース | ログイン状態管理 |
| WMFSettingsTableViewCell.swift | `Wikipedia/Code/WMFSettingsTableViewCell.swift` | ソース | 設定セルUI |
