XCoordinatorのREADMEを和訳してみた


Coordinatorパターンを採用する際に便利なライブラリがあると言うことなので使おうとしましたが、和訳記事が見当たらなかったのでREADMEをできる限り和訳してみました。

https://github.com/quickbirdstudios/XCoordinator

Google翻訳をベースにしているので、もしかしたら意味が通ってない部分があるかと思いますがご容赦いただきたいです。
# XCoordinatorを使用する理由

- ナビゲーションコードはすでに記述されている。
- 関心事の分離
    - Coordinator：一連のルート
    - Route：ナビゲーション先
    - Transition：遷移の種類とアニメーション
- Coordinator、Router、Transitionをさまざまな組み合わせで再利用できる。
- CustomTransition/animationの完全サポート。
- 子View/コンテナビューの埋め込みのサポート。
- BasicCoordinatorが多くの使用ケースに適したジェネリッククラスであるため、独自のCoordinatorを作成する必要が少なくなる。

# 導入

## アプリの起動からXCoordinatorを使用する

1. `Info.plist`の`Storyboard file base name`から`Main`を削除

2. 下のコードを`AppDelegate.swift`に追加

```swift
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    let window: UIWindow! = UIWindow()
    let router = AppCoordinator().strongRouter

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        router.setRoot(for: window)
        return true
    }
}
```
## XCoordinatorを使用する
接続したいViewを含む列挙型を作成します。

```swift
enum UserListRoute: Route {
    case home
    case users
    case user(String)
    case registerUsersPeek(from: Container)
    case logout
}
```

`Route`に書かれている経路は、どの`Route`に`trigger`できるかを表します。

`Coordinator`は`trigger`された`Route`に基づいて、遷移の準備を担当します。

```swift
class UserListCoordinator: NavigationCoordinator<UserListRoute> {
    init() {
        super.init(initialRoute: .home)
    }

    override func prepareTransition(for route: UserListRoute) -> NavigationTransition {
        switch route {
        case .home:
            let viewController = HomeViewController.instantiateFromNib()
            let viewModel = HomeViewModelImpl(router: unownedRouter)
            viewController.bind(to: viewModel)
            return .push(viewController)
        case .users:
            let viewController = UsersViewController.instantiateFromNib()
            let viewModel = UsersViewModelImpl(router: unownedRouter)
            viewController.bind(to: viewModel)
            return .push(viewController, animation: .interactiveFade)
        case .user(let username):
            let coordinator = UserCoordinator(user: username)
            return .present(coordinator, animation: .default)
        case .registerUsersPeek(let source):
            return registerPeek(for: source, route: .users)
        case .logout:
            return .dismiss()
        }
    }
}
```

`UserListRoute`は、フローの`trigger`を定義する列挙型を作成します。

例えば`.home`が`trigger`されると`HomeViewController`が表示されます。

`Route`は、CoordinatorまたはViewModel内から`trigger`されます。
下記のコードはViewModel内からRouteをtriggerする方法です。

```swift
class HomeViewModel {
    let router: UnownedRouter<HomeRoute>

    init(router: UnownedRouter<HomeRoute>) {
        self.router = router
    }

    /* ... */

    func usersButtonPressed() {
        router.trigger(.users)
    }
}
```

# コンポーネント

## Route

関連するナビゲーションパス

## Coordinator/ルーター

Viewを読み込み、triggerされたRouteに基づいてviewModelsを作成するオブジェクト。

###StrongRouter
元のCoordinatorへの強い参照を保持しています。子Coordinatorを保持したり、AppDelegateで特定のルーターを指定したりできます。

###WeakRouter
元のCoordinatorへの弱い参照を保持しています。viewControllerまたはviewModelにCoordinatorを保持できます。また、兄弟または親のCoordinatorへの参照を保持するために使用することもできます。

###UnownedRouter
元のCoordinatorへの所有されていない参照を保持します。viewControllerまたはviewModelにCoordinatorを保持できます。また、兄弟または親のCoordinatorへの参照を保持するために使用することもできます。

## Transition

遷移方法を指定できる。使用中のrootViewControllerのタイプに基づいて利用できます。

例：ViewTransitionはすべてのrootViewControllerがサポートする基本的なTransitionのみをサポートしますが、NavigationTransitionはNavigationController固有のTransitionを追加します。

使用可能な遷移タイプは次のとおりです。

###present
View階層の最上位にViewControllerを提示します
(rootViewControllerからする場合は、presentOnRootを使用します）
###embed
ViewControllerをコンテナビューに埋め込みます
###dismiss
最も上位に表示されているViewControllerを却下します
（dismissToRootを使用してrootViewControllerでdismissを呼び出します）
###none
何もしません。Routeを無視したり、テスト目的で使用したりできます。
###push
ViewControllerをNavigationStackにpushします
（NavigationTransition内のみ）
###pop
NavigationStackからトップビューコントローラーをpopします
（NavigationTransition内のみ）
###popToRoot
rootViewControllerを除くNavigationStack上のすべてのViewControllerをpopします
（NavigationTransition内のみ）

#Coordinatorパターン参考記事

https://qiita.com/ryotapoi/items/80cc67f598589911e08b

https://ichi.pro/swift-5-no-ko-dhine-ta-dezainpata-n-o-katsuyosuru-225793844678162

間違い等あればご指摘いただけると幸いです。