# Wikipedia iOS コードリーディングガイドライン

## はじめに

このガイドラインは、Wikipedia iOS アプリのコードベースを効率的に理解するための手引きです。
Swift/Objective-Cに精通していないエンジニアでも、段階的に学習できるよう構成されています。

**対象読者:**
- プロジェクトに新規参画するエンジニア
- 他言語からの経験者
- コードレビューを行う担当者

---

## 1. 言語基礎

> このセクションでは、Swift/Objective-Cの基本構文と概念を解説します。

### 1.1 プログラム構造

このプロジェクトは**Swift**をメイン言語として使用し、一部のレガシーコードは**Objective-C**で記述されています。

**Swiftファイルの基本構造:**

```swift
// ファイル: Wikipedia/Code/AppDelegate.swift:1-17
import UIKit
import BackgroundTasks
import CocoaLumberjackSwift

#if TEST
// 条件付きコンパイル - テスト時のみ実行
@main
class MockAppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        return true
    }
}
#else
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    // 本番用のAppDelegate実装
}
#endif
```

**Objective-Cファイルの基本構造:**

```objc
// ファイル: Wikipedia/Code/MWKDataStore.h:1-10
#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>
#import <WMF/WMFBlockDefinitions.h>

@class MWKSavedPageList;
@class WMFArticle;
// ...
```

### 1.2 データ型と変数

**プロパティ宣言（Swift）:**

```swift
// ファイル: Wikipedia/Code/ArticleViewController.swift:29-36
/// Article holds article metadata (displayTitle, description, etc) and user state
internal var article: WMFArticle
internal var mediaList: MediaList?

/// 明示的なプロパティ宣言
@objc public var articleURL: URL
let articleLanguageCode: String

/// オプショナル（nil許容）
var currentETag: String?
```

**プロパティ宣言（Objective-C）:**

```objc
// ファイル: Wikipedia/Code/MWKDataStore.h:59-62
@property (readonly, strong, nonatomic) NSURL *containerURL;
@property (readonly, strong, nonatomic) WMFSession *session;
@property (readonly, strong, nonatomic) WMFConfiguration *configuration;
```

### 1.3 制御構造

**条件分岐:**

```swift
// ファイル: WMF Framework/Router.swift:64-70
switch namespace {
case .talk:
    if project.supportsNativeUserTalkPages {
        return .talk(url)
    } else {
        return nil
    }
case .userTalk:
    return project.supportsNativeUserTalkPages ? .userTalk(url) : nil
// ...
default:
    return nil
}
```

**ガード文（早期リターン）:**

```swift
// ファイル: WMF Framework/Router.swift:28-38
guard let siteURL = url.wmf_site,
    let project = WikimediaProject(siteURL: siteURL) else {
    guard url.isWikimediaHostedAudioFileLink else {
        return webViewDestinationForHostURL(url)
    }
    return .audio(url.byMakingAudioFileCompatibilityAdjustments)
}
```

### 1.4 関数/メソッド定義

**通常のメソッド:**

```swift
// ファイル: WMF Framework/Configuration.swift:232-235
public func pageContentServiceBuilder(withWikiHost wikiHost: String? = nil) -> APIURLComponentsBuilder {
    let builder = pageContentServiceAPIType.builder(withWikiHost: wikiHost)
    return builder
}
```

**クロージャを受け取るメソッド:**

```swift
// ファイル: WMF Framework/Fetcher.swift:31-58
@discardableResult public func requestMediaWikiAPIAuthToken(
    for URL: URL?,
    type: TokenType,
    cancellationKey: CancellationKey? = nil,
    completionHandler: @escaping (Result<Token, Error>) -> Swift.Void
) -> URLSessionTask? {
    // 非同期処理の実装
}
```

### 1.5 モジュール/インポート

```swift
// ファイル: Wikipedia/Code/ArticleViewController.swift:1-5
import WMF                // WMFフレームワーク - 共通ロジック
import SwiftUI            // UIフレームワーク
import CocoaLumberjackSwift  // ログ出力ライブラリ
import WMFComponents      // UIコンポーネント（Swift Package）
import WMFData            // データ層（Swift Package）
```

---

## 2. プロジェクト固有の概念

> このセクションでは、当プロジェクト特有の概念を解説します。

### 2.1 フレームワーク固有の概念

**UIKit + SwiftUIのハイブリッド構成:**

このプロジェクトはUIKitベースですが、新しい機能ではSwiftUIも使用しています。

```swift
// ファイル: Wikipedia/Code/ArticleViewController.swift:8
class ArticleViewController: ThemeableViewController, HintPresenting, UIScrollViewDelegate, WMFNavigationBarConfiguring, WMFNavigationBarHiding {
```

**Coordinatorパターン:**

ナビゲーションフローはCoordinatorパターンで管理されています。

```swift
// ファイル: Wikipedia/Code/Coordinator.swift:1-15
@MainActor
protocol Coordinator: AnyObject {
    var navigationController: UINavigationController { get }

    @discardableResult
    func start() -> Bool
}
```

**Theme（テーマ）システム:**

アプリ全体でダークモード/ライトモードをサポートするThemeable プロトコル。

```swift
// ファイル: Wikipedia/Code/ThemeableViewController.swift:1-14
class ThemeableViewController: UIViewController, Themeable {
    var theme: Theme = Theme.standard

    func apply(theme: Theme) {
        self.theme = theme
    }
}
```

### 2.2 プロジェクト独自のパターン

**データストアパターン（MWKDataStore）:**

アプリのデータアクセス層の中心となるクラス。Core Dataコンテキスト、セッション、設定を管理。

```objc
// ファイル: Wikipedia/Code/MWKDataStore.h:41-82
@interface MWKDataStore : NSObject

@property (readonly, strong, nonatomic) WMFSession *session;
@property (readonly, strong, nonatomic) WMFConfiguration *configuration;
@property (readonly, strong, nonatomic) WMFPermanentCacheController *cacheController;
@property (readonly, strong, nonatomic) WMFAuthenticationManager *authenticationManager;
@property (readonly, strong, nonatomic) MWKSavedPageList *savedPageList;
@property (readonly, strong, nonatomic) WMFReadingListsController *readingListsController;
// ...
@end
```

**Fetcherパターン:**

APIリクエストを行う基底クラス。

```swift
// ファイル: WMF Framework/Fetcher.swift:11-29
@objc(WMFFetcher)
open class Fetcher: NSObject {
    @objc public let configuration: Configuration
    @objc public let session: Session

    @objc required public init(session: Session, configuration: Configuration) {
        self.session = session
        self.configuration = configuration
    }
}
```

**Routerパターン:**

URLルーティングを処理し、適切な画面遷移先を決定。

```swift
// ファイル: WMF Framework/Router.swift:1-17
@objc(WMFRouter)
public class Router: NSObject {
    public enum Destination: Equatable {
        case inAppLink(_: URL)
        case externalLink(_: URL)
        case article(_: URL)
        case articleHistory(_: URL, articleTitle: String)
        case articleDiff(_: URL, fromRevID: Int?, toRevID: Int?)
        case talk(_: URL)
        case userTalk(_: URL)
        case search(_: URL, term: String?)
        // ...
    }
}
```

---

## 3. 命名規則

> このセクションでは、プロジェクト全体で使用される命名規則を解説します。

### 3.1 ファイル・ディレクトリ命名

| パターン | 意味 | 例 |
|---------|------|-----|
| `{クラス名}.swift` | メインクラス定義 | `ArticleViewController.swift` |
| `{クラス名}+{機能}.swift` | 拡張ファイル | `ArticleViewController+Editing.swift` |
| `{クラス名}+CoreDataClass.swift` | Core Dataモデル | `WMFArticle+CoreDataClass.swift` |
| `{クラス名}+CoreDataProperties.swift` | Core Dataプロパティ | `WMFArticle+CoreDataProperties.swift` |
| `{機能名}Controller.swift` | コントローラークラス | `CacheController.swift` |
| `{機能名}Coordinator.swift` | ナビゲーションコーディネーター | `ArticleCoordinator.swift` |
| `{機能名}Fetcher.swift` | APIフェッチャー | `ArticleFetcher.swift` |

### 3.2 クラス・関数・変数命名

| プレフィックス/サフィックス | 意味 | 例 |
|---------------------------|------|-----|
| `WMF` | Wikimedia Foundation共通コード | `WMFArticle`, `WMFSession` |
| `MWK` | MediaWiki Kit（レガシー） | `MWKDataStore`, `MWKSavedPageList` |
| `ViewController` | UIViewControllerサブクラス | `ArticleViewController` |
| `Coordinator` | ナビゲーション管理 | `ArticleCoordinator` |
| `Controller` | ビジネスロジック管理 | `CacheController` |
| `Fetcher` | APIリクエスト処理 | `ArticleFetcher` |
| `Themeable` | テーマ適用対応 | `ThemeableViewController` |
| `wmf_` | Objective-Cメソッドプレフィックス | `wmf_URLWithLanguageVariantCode` |

### 3.3 プログラム分類一覧

| 分類 | 説明 | 配置場所 |
|-----|------|---------|
| ViewControllers | UI表示・制御 | `Wikipedia/Code/` |
| Coordinators | 画面遷移管理 | `Wikipedia/Code/` |
| Fetchers | APIアクセス | `WMF Framework/` |
| Controllers | ビジネスロジック | `WMF Framework/` |
| Models | データモデル | `WMF Framework/`, `WMFData/` |
| Extensions | 既存クラス拡張 | `WMF Framework/` |
| Components | 再利用可能UI | `WMFComponents/` |

---

## 4. ディレクトリ構造

> このセクションでは、プロジェクトのディレクトリ構造を解説します。

```
wikipedia-ios-main/
├── Wikipedia/                    # メインアプリターゲット
│   ├── Code/                     # アプリのソースコード（~900ファイル）
│   │   ├── AppDelegate.swift     # アプリエントリーポイント
│   │   ├── SceneDelegate.swift   # シーンライフサイクル管理
│   │   ├── WMFAppViewController.m # メインタブバーコントローラー
│   │   ├── Article*.swift        # 記事表示関連
│   │   ├── *Coordinator.swift    # ナビゲーション
│   │   └── ...
│   ├── Localizations/            # 多言語リソース
│   └── Third Party Code/         # サードパーティライブラリ
├── WMF Framework/                # 共有フレームワーク
│   ├── Configuration.swift       # 環境設定
│   ├── Fetcher.swift             # API基底クラス
│   ├── Router.swift              # URLルーティング
│   ├── Theme.swift               # テーマ定義
│   ├── Remote Notifications/     # プッシュ通知
│   └── ...
├── WMFData/                      # データ層（Swift Package）
│   └── Sources/WMFData/
│       └── Models/               # データモデル
├── WMFComponents/                # UIコンポーネント（Swift Package）
│   └── Sources/WMFComponents/
│       ├── Components/           # 再利用可能UIパーツ
│       └── Style/                # スタイル定義
├── Widgets/                      # ウィジェット拡張
├── ContinueReadingWidget/        # 続きを読むウィジェット
├── NotificationServiceExtension/ # 通知サービス拡張
├── WikipediaUnitTests/           # ユニットテスト
├── WikipediaUITests/             # UIテスト
├── scripts/                      # ビルド・セットアップスクリプト
├── fastlane/                     # CI/CD設定
└── docs/                         # ドキュメント
```

### 各ディレクトリの役割

| ディレクトリ | 役割 | 主要ファイル |
|-------------|------|-------------|
| `Wikipedia/Code/` | アプリUI・ビジネスロジック | `ArticleViewController.swift`, `*Coordinator.swift` |
| `WMF Framework/` | 共有フレームワーク（アプリ+拡張機能） | `Configuration.swift`, `Fetcher.swift`, `Theme.swift` |
| `WMFData/` | データモデル・ビジネスロジック | `WMFArticleSummary.swift`, `WMFProject.swift` |
| `WMFComponents/` | 再利用可能UIコンポーネント | `WMFSourceEditorViewController.swift` |
| `Widgets/` | ホーム画面ウィジェット | ウィジェット表示ロジック |
| `scripts/` | 開発環境セットアップ | `setup`, `localize.py` |

---

## 5. アーキテクチャ

> このセクションでは、プロジェクトのアーキテクチャパターンを解説します。

### 5.1 全体アーキテクチャ

Wikipedia iOSアプリは**レイヤードアーキテクチャ**と**Coordinatorパターン**を組み合わせた構成を採用しています。

```
┌─────────────────────────────────────────────────────────────┐
│                    Presentation Layer                        │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │ViewControllers│  │Coordinators│  │  SwiftUI Views     │  │
│  └──────┬──────┘  └──────┬──────┘  └─────────┬───────────┘  │
└─────────┼────────────────┼───────────────────┼──────────────┘
          │                │                   │
┌─────────┼────────────────┼───────────────────┼──────────────┐
│         │          Business Layer            │              │
│  ┌──────┴──────┐  ┌──────┴──────┐  ┌────────┴────────┐     │
│  │ Controllers │  │   Fetchers  │  │  DataControllers │     │
│  └──────┬──────┘  └──────┬──────┘  └────────┬────────┘     │
└─────────┼────────────────┼───────────────────┼──────────────┘
          │                │                   │
┌─────────┼────────────────┼───────────────────┼──────────────┐
│         │            Data Layer              │              │
│  ┌──────┴──────┐  ┌──────┴──────┐  ┌────────┴────────┐     │
│  │  Core Data  │  │   Session   │  │  Configuration  │     │
│  │ (MWKDataStore)│ │  (Network) │  │   (API URLs)   │     │
│  └─────────────┘  └─────────────┘  └─────────────────┘     │
└─────────────────────────────────────────────────────────────┘
```

### 5.2 レイヤー構成

| レイヤー | 責務 | 代表的なファイル |
|---------|------|-----------------|
| Presentation | UI表示、ユーザー操作 | `ArticleViewController.swift`, `ThemeableViewController.swift` |
| Navigation | 画面遷移、フロー管理 | `ArticleCoordinator.swift`, `Router.swift` |
| Business | ビジネスロジック | `CacheController.swift`, `ArticleFetcher.swift` |
| Data | データ永続化、API通信 | `MWKDataStore.m`, `Session.swift`, `Configuration.swift` |

### 5.3 データフロー

1. **ユーザー操作** → ViewController
2. ViewController → **Coordinator**（画面遷移の場合）
3. ViewController → **Fetcher**（データ取得の場合）
4. Fetcher → **Session** → API
5. API → Session → Fetcher → **ViewController**（UI更新）
6. データ永続化: **MWKDataStore**（Core Data）

---

## 6. 主要コンポーネント

> このセクションでは、主要なコンポーネントとその連携を解説します。

### 6.1 エントリーポイント

**AppDelegate:**

```swift
// ファイル: Wikipedia/Code/AppDelegate.swift:17-41
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    let appViewController = WMFAppViewController()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        registerUserDefaults()
        UIApplication.shared.registerForRemoteNotifications()
        updateDynamicIconShortcutItems()
        registerBackgroundTasks()
        return true
    }
}
```

**SceneDelegate:**

```swift
// ファイル: Wikipedia/Code/SceneDelegate.swift:25-50
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    let window = UIWindow(windowScene: windowScene)
    self.window = window

    // ディープリンク、URL、ショートカット処理
    if let userActivity = connectionOptions.userActivities.first {
        processUserActivity(userActivity)
    }

    appViewController.launchApp(in: window, waitToResumeApp: appNeedsResume)
}
```

**WMFAppViewController:**

メインのUITabBarController。アプリのルートビューコントローラー。

```objc
// ファイル: Wikipedia/Code/WMFAppViewController.h:14
@interface WMFAppViewController : UITabBarController <UNUserNotificationCenterDelegate>
```

### 6.2 ビジネスロジック

**ArticleCoordinator（記事画面遷移）:**

```swift
// ファイル: Wikipedia/Code/ArticleCoordinator.swift:146-228
final class ArticleCoordinator: NSObject, Coordinator, ArticleTabCoordinating {
    let navigationController: UINavigationController
    private(set) var articleURL: URL?
    private let dataStore: MWKDataStore
    var theme: Theme

    @MainActor @discardableResult
    func start() -> Bool {
        guard let articleVC = ArticleViewController(articleURL: articleURL, dataStore: dataStore, theme: theme, source: source) else {
            return false
        }
        navigationController.pushViewController(articleVC, animated: needsAnimation)
        return true
    }
}
```

**ArticleFetcher（記事データ取得）:**

```swift
// ファイル: Wikipedia/Code/ArticleViewController.swift:126
internal lazy var fetcher: ArticleFetcher = ArticleFetcher(session: session, configuration: configuration)
```

### 6.3 データアクセス

**MWKDataStore:**

```objc
// ファイル: Wikipedia/Code/MWKDataStore.h:100-107
- (nullable WMFArticle *)fetchArticleWithURL:(NSURL *)URL;
- (nullable WMFArticle *)fetchOrCreateArticleWithURL:(NSURL *)URL;
- (nullable WMFArticle *)fetchArticleWithKey:(NSString *)key variant:(nullable NSString *)variant;
- (BOOL)save:(NSError **)error;
```

**Session（ネットワーク通信）:**

```swift
// ファイル: Wikipedia/Code/Session.swift:27-60
@objc(WMFSession)
public class Session: NSObject {
    public struct Request {
        public enum Method {
            case get
            case post
            case put
            case delete
            case head
        }
        public enum Encoding {
            case json
            case form
            case html
        }
    }
}
```

### 6.4 ユーティリティ/共通機能

**Configuration（API URL設定）:**

```swift
// ファイル: WMF Framework/Configuration.swift:40-55
@objc public static let current: Configuration = {
    #if WMF_LOCAL
    return Configuration.local(options: [.localPCS, .localAnnouncements])
    #elseif WMF_STAGING
    return Configuration.staging(options: [])
    #else
    return .production
    #endif
}()
```

**Theme（テーマ管理）:**

```swift
// ファイル: WMF Framework/Theme.swift:93-100
@objc(WMFColors)
public class Colors: NSObject {
    fileprivate static let light = Colors(identifier: .light)
    fileprivate static let sepia = Colors(identifier: .sepia)
    fileprivate static let dark = Colors(identifier: .dark)
}
```

---

## 7. よく使われるパターン

> このセクションでは、コード内で頻出するパターンを解説します。

### パターン一覧

| パターン | 説明 | 出現頻度 | 代表的なファイル |
|---------|------|---------|-----------------|
| Coordinator | 画面遷移管理 | 高 | `ArticleCoordinator.swift` |
| Fetcher | API通信の抽象化 | 高 | `Fetcher.swift`, `ArticleFetcher.swift` |
| Themeable | テーマ適用 | 高 | `ThemeableViewController.swift` |
| Extension | 機能分割 | 高 | `ArticleViewController+Editing.swift` |
| Protocol-Delegate | イベント通知 | 中 | `WatchlistControllerDelegate` |

### 各パターンの詳細

#### パターン1: Coordinator

**目的:** 画面遷移ロジックをViewControllerから分離し、テスト容易性と保守性を向上させる。

**実装例:**
```swift
// ファイル: Wikipedia/Code/Coordinator.swift:9-15
@MainActor
protocol Coordinator: AnyObject {
    var navigationController: UINavigationController { get }

    @discardableResult
    func start() -> Bool
}
```

**解説:** 各画面遷移フローはCoordinatorクラスが管理。ViewControllerは表示ロジックに専念し、遷移先の決定はCoordinatorに委譲。

#### パターン2: Fetcher

**目的:** ネットワークリクエストの共通処理を基底クラスに集約。

**実装例:**
```swift
// ファイル: WMF Framework/Fetcher.swift:11-29
@objc(WMFFetcher)
open class Fetcher: NSObject {
    @objc public let configuration: Configuration
    @objc public let session: Session

    @objc required public init(session: Session, configuration: Configuration) {
        self.session = session
        self.configuration = configuration
    }
}
```

**解説:** Session（実際の通信処理）とConfiguration（URL構築）を組み合わせ、APIリクエストを実行。各APIエンドポイント用のFetcherサブクラスを作成。

#### パターン3: Extension分割

**目的:** 大きなクラスを機能別ファイルに分割し、可読性を向上。

**実装例:**
```
ArticleViewController.swift          # メインクラス（66KB）
ArticleViewController+Editing.swift  # 編集機能
ArticleViewController+Media.swift    # メディア表示
ArticleViewController+Sharing.swift  # 共有機能
ArticleViewController+Tooltips.swift # ツールチップ
```

**解説:** `+`記法でExtensionファイルを命名。機能ごとにファイルを分割することで、変更箇所の特定が容易になる。

---

## 8. 業務フロー追跡の実践例

> このセクションでは、実際の業務フローをコードで追跡する方法を解説します。

### 8.1 フロー追跡の基本手順

1. エントリーポイントを特定
2. 処理の流れを追跡（呼び出し関係を追う）
3. データの変換を確認
4. 最終的な出力を確認

### 8.2 フロー追跡の実例

#### 例1: 記事を開く

**概要:** URLから記事画面を表示するまでの流れ

**処理フロー:**
```
SceneDelegate → Router → ArticleCoordinator → ArticleViewController
```

**詳細な追跡:**

1. **URL受信** (`Wikipedia/Code/SceneDelegate.swift:123-125`)
   ```swift
   func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
       openURLContexts(URLContexts)
   }
   ```

2. **UserActivity生成** (`Wikipedia/Code/SceneDelegate.swift:127-154`)
   ```swift
   private func openURLContexts(_ URLContexts: Set<UIOpenURLContext>) {
       guard let firstURL = URLContexts.first?.url else { return }
       guard let activity = NSUserActivity.wmf_activity(forWikipediaScheme: firstURL) else {
           resumeAppIfNecessary()
           return
       }
       _ = appViewController.processUserActivity(activity, animated: false)
   }
   ```

3. **ルーティング判定** (`WMF Framework/Router.swift:28-41`)
   ```swift
   public func destination(for url: URL, permanentUsername: String?) -> Destination {
       guard let siteURL = url.wmf_site,
           let project = WikimediaProject(siteURL: siteURL) else {
           return webViewDestinationForHostURL(url)
       }
       return destinationForHostURL(url, project: project, permanentUsername: permanentUsername)
   }
   ```

4. **記事画面起動** (`Wikipedia/Code/ArticleCoordinator.swift:177-228`)
   ```swift
   @MainActor @discardableResult
   func start() -> Bool {
       guard let articleVC = ArticleViewController(articleURL: articleURL, dataStore: dataStore, theme: theme, source: source) else {
           return false
       }
       navigationController.pushViewController(articleVC, animated: needsAnimation)
       return true
   }
   ```

### 8.3 フロー追跡チェックリスト

- [ ] エントリーポイントを特定したか
- [ ] 呼び出し関係を把握したか
- [ ] データの変換ポイントを確認したか
- [ ] エラーハンドリングを確認したか
- [ ] 最終的な出力を確認したか

---

## 9. 設計書の参照順序

> このセクションでは、プロジェクト理解のための設計書参照順序を案内します。

### 9.1 目的別ロードマップ

#### 全体像を把握したい場合
1. `README.md` - プロジェクト概要、ビルド手順
2. `docs/process.md` - 開発プロセス
3. このコードリーディングガイドライン

#### 特定機能を理解したい場合
1. 該当するCoordinatorを特定
2. ViewControllerの実装を確認
3. 関連するFetcherとAPIを確認

#### 改修作業を行う場合
1. 影響範囲のCoordinatorを確認
2. ViewController + Extensionを確認
3. テストケース（`WikipediaUnitTests/`）を確認

### 9.2 ドキュメント一覧

| ドキュメント | 概要 | 参照タイミング |
|-------------|------|---------------|
| `README.md` | ビルド手順、開発環境セットアップ | 初回参画時 |
| `docs/process.md` | 開発プロセス、コードレビュー規約 | PR作成時 |
| `docs/ci.md` | CI/CD設定 | ビルド問題発生時 |
| `docs/localization.md` | 多言語対応手順 | 翻訳追加時 |
| `docs/languages.md` | Wikipedia言語設定 | 言語機能変更時 |
| `docs/web_dev.md` | Web開発（記事表示用） | 記事表示カスタマイズ時 |

---

## 10. トラブルシューティング

> このセクションでは、コードリーディング時によくある問題と解決法を解説します。

### よくある疑問と回答

#### Q: `WMF`プレフィックスと`MWK`プレフィックスの違いは？
A: `WMF`は新しいコード、`MWK`はレガシーコードを示します。`MWK`は「MediaWiki Kit」の略で、Objective-C時代に作られたものです。可能であれば`WMF`を使用してください。

#### Q: `@objc`属性が付いているのはなぜ？
A: Objective-Cコードとの相互運用のためです。`WMFAppViewController.m`などのObjective-CファイルからSwiftコードを呼び出す際に必要です。

#### Q: 大きなファイル（ArticleViewController.swift等）を効率的に読むには？
A: Extension分割（`+`ファイル）を活用してください。例えば編集機能は`ArticleViewController+Editing.swift`にあります。

#### Q: テーマ関連のコードはどこにある？
A: `WMF Framework/Theme.swift`にTheme定義、各ViewControllerは`Themeable`プロトコルを実装。`apply(theme:)`メソッドでテーマを適用します。

### デバッグのヒント

**ログレベル:**
```
🗣️ Verbose
💬 Debug
ℹ️ Info
⚠️ Warning
🚨 Error
```

デフォルトではWarningとErrorのみコンソール出力されます。全ログを出力するには：

```swift
// WMFLogging.h の DDLogLevelAll を変更
```

**シミュレーターのコンテナパス:**
デバッグビルド時、起動ログにシミュレーターのコンテナパスが出力されます。Core Dataファイルの確認に使用できます。

---

## 付録

### A. 用語集

| 用語 | 説明 |
|-----|------|
| WMF | Wikimedia Foundation - ウィキメディア財団 |
| MWK | MediaWiki Kit - レガシーコードのプレフィックス |
| PCS | Page Content Service - 記事コンテンツAPI |
| Core Data | Appleのデータ永続化フレームワーク |
| Coordinator | 画面遷移を管理するデザインパターン |
| Themeable | テーマ適用可能であることを示すプロトコル |
| RESTBase | WikimediaのRESTful API |
| Beta Cluster | MediaWikiのテスト環境 |

### B. ファイル一覧

| ファイル/ディレクトリ | 説明 | 主な内容 |
|---------------------|------|---------|
| `Wikipedia/Code/AppDelegate.swift` | アプリエントリーポイント | 初期化、バックグラウンド処理 |
| `Wikipedia/Code/SceneDelegate.swift` | シーンライフサイクル | ウィンドウ管理、URL処理 |
| `Wikipedia/Code/WMFAppViewController.*` | メインタブバー | タブ管理、ナビゲーション |
| `Wikipedia/Code/ArticleViewController.swift` | 記事表示 | WebView、ツールバー |
| `Wikipedia/Code/*Coordinator.swift` | 画面遷移管理 | ナビゲーションフロー |
| `WMF Framework/Configuration.swift` | API設定 | URL構築、環境切替 |
| `WMF Framework/Fetcher.swift` | API基底クラス | ネットワークリクエスト |
| `WMF Framework/Theme.swift` | テーマ定義 | 色、フォント |
| `WMFData/` | データ層パッケージ | モデル、ビジネスロジック |
| `WMFComponents/` | UIパッケージ | 再利用可能コンポーネント |

### C. 参考資料

- [Swift API Design Guidelines](https://swift.org/documentation/api-design-guidelines/)
- [Apple Coding Guidelines for Cocoa](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html)
- [MediaWiki API](https://www.mediawiki.org/wiki/API:Main_page)
- [Wikimedia REST API](https://www.mediawiki.org/wiki/REST_API)
- [SwiftLint](https://github.com/realm/SwiftLint)
