Carthageを使ってみよう


## Carthageとは
Carthage（カーセッジ）とはiOS / OS X開発のためのライブラリの依存管理システムです。よく使われている既存のシステムといえばCocoaPodsですが、CarthageはCocoaPodsにはない利点があるため最近よく使われています。

Carthageの基本的な導入フローは以下のようになります。

* プロジェクトで使用するフレームワークをリストしたCartfileを作成します。
* Carthageを実行します。Carthageを実行すると、リストにある各フレームワークを取り出してビルドが行われます。
* ビルドされた.frameworkバイナリをアプリケーションのXcodeプロジェクトにドラッグします。

Carthageはプロジェクトファイルやビルド設定を自動的に変更することなく、依存関係の構築とフレームワークのバイナリを作成できます。

参考URL：https://github.com/Carthage/Carthage

## CocoaPodsとCarthageの違い
CocoaPodsは基本的に自動で依存関係のすべての作成、更新をお任せでやってくれる使いやすい仕組みになっています。一方、Carthageはプロジェクトへの繋ぎこみ（統合）の部分をユーザがやる必要があるため、若干手間がかかる仕組みになっています。

CocoaPodsでは中央集権的なシステムになっていて、ライブラリが一箇所に集中しており一覧になっていますが、Carthageは逆に一覧がなく、Githubなどから取得するような形になっています。

ここまで聞くとCocoaPodsの方が便利なように聞こえます。実際、Carthageにはない様々な機能がCocoaPodsには存在します。しかし、実際のところそこまでの機能は不要なことが多く、よりシンプルで高速に動作する仕組みが望まれた中で生まれたのがCarthageです。

CarthageはCocoaPodsとは異なりシンプルであり、それが大きなメリットとなっています。

参考URL：https://qiita.com/nori0620/items/b81ae171f0e82b0c2d8a

## Carthageを使う理由
CocoaPodsとCarthageにはそれぞれ利点、欠点があり、個々のライブラリの対応状況によっても選択肢は変わります。ただ、個人的にはCarthage対応のライブラリについてはCocoaPodsを使わないという方針を取っています。その大きな理由が **コンパイル時間の短縮** です。Carthageはライブラリを事前にビルドするようになっているため、CocoaPodsに比べて本体のコードのコンパイル時間が短くなるため、開発スピードの向上に寄与します。

参考URL：https://qiita.com/yutat93/items/97fe9bc2bf2e97da7ec1

## インストール方法
【方法1】

[GitHubのreleases](https://github.com/Carthage/Carthage/releases)にある Carthage.pkg をダウンロードしてインストールする。

【方法2】
以下のコマンド（Homebrew）を利用してインストールすることもできます。

```
$ brew update
$ brew install carthage
```

## Carthageコマンド
``` shell-session:carhageコマンドの結果
$ carthage
Available commands:

   archive           Archives built frameworks into a zip that Carthage can use
   bootstrap         Check out and build the project's dependencies
   build             Build the project's dependencies
   checkout          Check out the project's dependencies
   copy-frameworks   In a Run Script build phase, copies each framework specified by a SCRIPT_INPUT_FILE environment variable into the built app bundle
   fetch             Clones or fetches a Git repository ahead of time
   help              Display general or command-specific help
   outdated          Check for compatible updates to the project's dependencies
   update            Update and rebuild the project's dependencies
   version           Display the current version of Carthage
```

ユーザであれば基本carthage update/bootstrapを使うことになります。簡単に各コマンドの説明を入れると以下のようになります。

```
・archive：フレームワークをzip化する。ビルド済みバイナリの提供などで利用
・bootstrap：プロジェクトの依存関係をチェックアウトしてビルドする。ライブラリを更新せずに取り込むだけならこっちを使う。Jenkinsなどはこちらにするといいかも
・build：プロジェクトの依存関係をビルドする。update/bootstrapは自動でビルドが走るが、うまくいかなかった場合にバイナリを生成し直す等で利用する
・checkout：プロジェクトの依存関係をチェックアウトする。sshでチェックアウトしたりできる
・copy-frameworks：XcodeのBuild Phase＞Run Scriptで実行するコマンド。SCRIPT_INPUT_FILE環境変数で指定された各フレームワークを、build app bundleにコピーする
・fetch：Gitのリポジトリからclone/fetchしてくるコマンド。使い道は不明
・help：読んで字のごとくヘルプ
・outdated：プロジェクトの依存関係の互換性アップデートの確認
・update：プロジェクトの依存関係の更新とビルド
・version：Carthageのバージョンを表示
```

参考URL：https://www.slideshare.net/syoikeda/carthagen

## 基本的な導入手順
```
・使用するライブラリの一覧を記述したCartfileを作成する
・carthage update --platform platform指定のコマンドで更新＋ビルドする
・XcodeからTargetにframeworkを追加する
・Build PhasesのRun Scriptを追加し、そこに/usr/local/bin/carthage copy-frameworksを追加する。また、Input Filesに追加したFrameworkのパスを設定し、Output Filesにもパスを追加する。
```

## Cartfileの作成
Cartfileをプロジェクトのルートフォルダーあたりに作成します。書き方は以下のような形です。

```
# githubからの場合(バージョンの指定がなければ最新を取得)
github "Alamofire/Alamofire" == 4.5.1
github "SwiftyBeaver/SwiftyBeaver"
github "ashleymills/Reachability.swift" ~> 3.0

# その他のGitサーバの場合
git "https://testgitserver.local/test/framework-name.git"
```

バージョン指定には3種類あり、`>= 1.0` は 1.0 以上で最新、`~> 1.0` は 1.0 以上 2.0 未満の最新、`== 1.0` は 1.0 になります。

## framework作成(checkout, build)

Cartfile があるフォルダーで `carthage update` を実行すると、依存関係をCarthage / Checkoutsフォルダにフェッチ＞ビルドされます（もしくは、コンパイル済みのframeworkをダウンロードしてきます）。

なお、更新はせずに指定されているバージョンを取り込むだけであれば`carthage bootstrap`を実行します。

ここで--platformオプションを指定することで、特定のプラットフォーム向けにビルドされます。--configurationオプションでDebug/Release向けにビルドできます。

## xcodeへの取り込み

ここまででframeworkが作成されているものの、それをプロジェクトに取り込む必要があります。

 * Carthage/BuildフォルダにあるframeworkをTargetのGeneralタブのLinked Frameworks and Librariesに追加する
 * Build Phaseタブの「＋」ボタンから「New Run Script Phase」を選択する
 * 新しくできたRun Scriptに「/usr/local/bin/carthage copy-frameworks」を記述する
 * Run ScriptのInput Filesに使用するframeworkへのパスを追加する
 * Run ScriptのOutput Filesにコピーしたframeworkへのパスを追加する（`$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/フレームワーク名.framework`）

いくつかの記事にはOutput Filesへのコピーが記載されてないものもありますが、元のgithubには明記されているのでOutput Filesにパスを追加するのは必須だと考えた方が良いと思います。

## 雑感

carthageを導入してみて思ったのは、「copy-frameworksのRun Scriptにパスを追加するのがめんどくさい」、「ビルド時間が本当に短くなる」、「carthage非対応がまだ結構ある」の3つでした。まだまだ当面はcocoaPodsとの併用が続くと思いますが、ビルド時間の短縮の面から言えばかなり有効なのでcarthage化を進めていきたいところです。