iOSアプリエンジニア向けの共有しやすいCocoaPods/fastlaneの準備,使い方,管理

CocoaPodsやfastlaneはiOSのプロジェクトファイルの範疇外なので、いろいろな導入や管理の方法があるのですが、かなりあとが辛くなるインストール手段が紹介されていることがあります、

今回はRubyでの開発者視点で、チーム開発を行う際などいろんな人とソースコードを共有する場合に管理が楽になる方法をまとめてみました。




## この記事の前提

### 対象

* Rubyはよく知らないけど、CocoaPods/fastlaneが導入したいiOSエンジニア 
* ターミナルの操作で `cd` とか `mkdir` など基本的なものはわかる

### 今回書かないこと

* 各ツールの詳しい使い方、説明
  * 今回はざらっと準備をするところまでを書いているので詳しい使い方は他のQiitaの記事を参考にしてください
* CocoaPodsのPodfileの書き方、fastlaneの用途別の記述方法
  * 初期ファイルのセットアップに重きをおいているので、セットアップ後のファイル記述は取り扱っていません 

### 前置き

* Rubyのバージョン管理は `anyenv` を使います
  * すでに `rbenv` が入っている人は「anyenvを入れる」と、「anyenvでrbenvをインストールする」は読み飛ばして頂いて大丈夫です
  * すでに `RVM` を使っている方は適宜読み替えてください。
* ターミナルではbashを使う想定です。 

## 準備

### anyenvを入れる

**envと呼ばれる、各プログラミング言語のバージョンを管理するものがあるのですが、それらを更に束ねて管理するのがanyenvです。

インストールは[GithubのINSTALL](https://github.com/riywo/anyenv)にもある通り以下のコマンドを実行する

```sh
$ git clone https://github.com/riywo/anyenv ~/.anyenv
```

そのあと、環境変数の情報を自身のProfileにセットする。今回はbashである想定なのでbashのProfileに記述します。

```sh
$ echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
$ exec $SHELL -l
```

ターミナルを一回 `exit` して開きなおして以下のコマンドで説明文が出てくればインストール成功です。

```sh:anyenvのヘルプ
$ anyenv help
Usage: anyenv <command> [<args>]

Some useful anyenv commands are:
   commands            List all available anyenv commands
   local               Show the local application-specific Any version
   global              Show the global Any version
   install             Install a **env
   uninstall           Uninstall a specific **anv
   version             Show the current Any version and its origin
   versions            List all Any versions available to **env
```

> **NOTE:**
> phpenvとrbenvが競合する可能性があるので
> サーバーサイドがPHPで構成されているアプリを開発する際に弊害になる恐れを鑑みて
> rbenvではなくanyenvを使う方法をご紹介しています。
> 参考：[anyenvでphpenvとrbenvの共存 \- Qiita](https://qiita.com/kawakami-kazuyoshi/items/bd148312815fb75818ee)


### rubyとbundlerをセットアップする

#### anyenvでrbenvをインストールする

anyenvでrubyのバージョンを管理する `rbenv` をインストールする。

```sh:rbenvのインストール
$ anyenv install rbenv
```

うまく入れば下記コマンドを打つと、`rbenv: ` のような形で表示される

```sh:anyenv管轄のもののバージョン確認
$ anyenv version
rbenv: 2.3.3 (set by /Users/You/.anyenv/envs/rbenv/version)
```

また、以下のコマンドでrbenvそのもののバージョンも確認できる。

```sh:rbenvのバージョン確認
$ rbenv --version
rbenv 1.1.1-30-gc8ba27f
```

#### rbenvで任意のrubyのバージョンをインストールする

rbenvを使うことにより複数のバージョンのrubyをつかえるようになり、Rubyのバージョンをチームで固定化することができます。

詳しいことは[自分の過去記事](https://qiita.com/shinkuFencer/items/3679cfd966f6a61ccd1b#rbenv%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B)で丁寧に説明しているので今回はダイジェストで `2.3.0` をインストール例を紹介します。

```sh:インストールできるバージョンの確認
$ rbenv install -l
Available versions:
  1.8.5-p52
  1.8.5-p113
  1.8.5-p114
  1.8.5-p115
  1.8.5-p231
  1.8.6
  1.8.6-p36
  1.8.6-p110
...(中略)...
  2.3.0-dev
  2.3.0-preview1
  2.3.0-preview2
  2.3.0
  2.3.1
  2.3.2
  2.3.3
  2.3.4
  2.3.5
  2.3.6
  2.3.7
  2.4.0-dev
  2.4.0-preview1
  2.4.0-preview2
  2.4.0-preview3
  2.4.0-rc1
  2.4.0
  2.4.1
...(後略)...
```

```sh:インストール
$ rbenv install 2.3.0
```

```sh:インストールされているrubyの確認
$ rbenv versions
  system
  2.3.0
```

ここで `2.3.0` と表示されればOK

#### 使うRubyのバージョンをプロジェクトで固定する

rbenvは `.ruby-version` と書かれたファイル内のバージョン番号のRubyをそのファイルがあるディレクトリでは使うようになります。


このあとRubyを使っていろいろなものをセットアップしていきますが、使うバージョンを明示的にすると便利です。

今回は一番簡単な方法で作成します。
以下がRubyのバージョンを2.3.0で固定したい場合のファイルの作り方です。

```sh:echoでファイルを作る方法
# CocoaPodsを入れたいiOSプロジェクトのディレクトリにcdで移動したあとに以下のコマンド
$ echo '2.3.0' > .ruby-version
```

> **NOTE:**
> やっていることはすごく単純で、バージョン番号が書かれた `.ruby-version` があれば
> そこに書かれているバージョンのRubyでスクリプトを実行します。

#### bundlerをインストールする

Rubyのプラグイン、Gemは普通に使うとグローバルに入ってしまいます。

グローバルに入れてしまうと他のプロジェクト入れたgemと依存しているとそれに引っ張られてしまうのでチームで同じ状態を保つというのが難しくなります

それを防ぐために特定ディレクトリに入れる仕組みがbundlerです。

bundlerはプロジェクトごとにgemを管理するパッケージマネージャ的な役割を果たします。

こちらも、詳しいことは[自分の過去記事](https://qiita.com/shinkuFencer/items/3679cfd966f6a61ccd1b#rbenv%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B)で説明していますが以下でインストールできます。

bundler自体もgemなので、これだけはグローバルにインストールします。

```sh:bundlerのインストール
$ gem install bundler
```


### bundlerでCocoaPods/fastlaneをセットアップする

#### Gemfileを用意する

CocoaPodsのバージョンを縛るために `Gemfile` を作ります。

ターミナルを開いて、入れたいXcodeのプロジェクトファイルにあるところに移動します。

```bash:bundler用のファイル生成コマンド
# ディレクトリ移動後に以下を実行
$ bundler init
```

Gemfileを編集します。
以下はCocoaPodsは1.2.1とfastlaneの2.100.1を入れる場合の記述です。

```ruby:Gemfile
# frozen_string_literal: true
source "https://rubygems.org"

gem 'cocoapods' , '1.2.1'
gem 'fastlane' , '2.100.1'
```

最新版の数値はいくつかというのを調べたければ [RubyGems\.org \| your community gem host](https://rubygems.org/) で調べると良いです。

* [cocoapods \| RubyGems\.org \| your community gem host](https://rubygems.org/gems/cocoapods)
* [fastlane \| RubyGems\.org \| your community gem host](https://rubygems.org/gems/fastlane)

#### bundlerを実行する

以下をシェルで実行

```bash:bundlerによるgemのインストール
$ bundle install --path vendor/bundle
```

> **NOTE:**
> vendor/bundle に CocoaPodsの実体ファイルを格納します。
> もし他のディレクトリが良い場合は適宜書き換えてください

インストールが成功したかを確認します。

```bash:各種確認コマンド
# CocoaPodsの確認
$ bundle exec pod --version
1.2.1

# fastlaneの確認
$ bundle exec fastlane -v
fastlane installation at path:
/Users/YourName/project/vendor/bundle/ruby/2.3.0/gems/fastlane-2.100.1/bin/fastlane
-----------------------------
[✔] 🚀
fastlane 2.100.1
```



## 使い方


### 実際にCocoaPodsを使う

記述するためのファイルを準備します。

```bash:ターミナルでPodfileの作成
$ bundle exec pod init
```

上記コマンドを打つと `Podfile` が出来上がるので
CocoaPodsで使いたいライブラリを `Podfile` に書きましょう

今回は試しにAlamofireを追加します。

```ruby:Podfile
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'Hoge' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for Hoge
  pod 'Alamofire'

  target 'HogeTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'HogeUITests' do
    inherit! :search_paths
    # Pods for testing
  end

end
```

実際に追加処理をしてみます。

```bash:ターミナルでPodfileの中身の追加を実行
$ bundle exec pod install
```

実行すると以下のような情報が流れます。
`Pod installation complete!` が表示されれば完了です。

```bash:実行ログ
Analyzing dependencies
Downloading dependencies
Installing Alamofire (4.6.0)
Generating Pods project
Integrating client project

Sending stats
Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.
```

> **NOTE:**
> よく例などで紹介される `pod install` と
> ここで紹介する `bundle exec pod install` はやっていることは同じです。
> システム（グローバル）にインストールされたCocoaPodsを使うか
> 今回のようなbundlerでバージョン指定をしたCocoaPodsを使うかの違いです。


### fastlaneの設定ファイルを準備する

プロジェクトの開始当初はfastlaneでやることはないと思うので設定ファイルだけ作っておきます。

```sh:fastlaneの初期セットアップ
bundle exec fastlane init
```

何に使いたいかを聞かれます

```sh:fastlaneのinit実行時に聞かれる表示
[00:00:00]: What would you like to use fastlane for?
1. 📸  Automate screenshots
2. 👩‍✈️  Automate beta distribution to TestFlight
3. 🚀  Automate App Store distribution
4. 🛠  Manual setup - manually setup your project to automate your tasks
?
```


あとで自身で設定をしていく場合は4を設定しておくとよいかと思うので 4 と入力してEnterを押します

あとは指示にしたがってEnterを押せば
`fastlane/Appfile` と `fastlane/Fastfile` が作られます。

```sh:確認
$ ls fastlane/
Appfile		Fastfile
```

あとはプロジェクトの方針に応じて、各ファイルの記述やfastlaneコマンドで設定ファイルを配置してください。

## 管理

* Rubyのバージョンを示した `.ruby-version`
* CocoaPods/fastlaneのバージョンを管理している `Gemfile` , `Gemfile.lock` ファイル
* CocoaPodsでインストールしたものを管理するPordfile
* fastlaneの設定ファイル群である `fastlane` ディレクトリ

この3種をGitなどのバージョン管理システムで管理しましょう。

### GemfileとGemfile.lock

`Gemfile` と `Gemfile.lock` は CocoaPodsをセットアップした際のバージョン情報が書き込まれています。

これをGitなどのバージョン管理システムで管理すれば、同じCocoaPodsのバージョンでセットアップが可能になります。

そのため、Xcodeのプロジェクトファイルと一緒に上記の2ファイルは保存しておくことをおすすめします。

### 別の人が新規でプロジェクトを触るときは

`Gemfile` と `Gemfile.lock` が用意されていれば、それを起点にgemを入れることができるので

```sh:他の人が開発する時に行うコマンド
$ bundler install
$ bundle exec pod install
```

を行えば、指定したバージョンのCocoaPodsでインストールを行うことができます。

もし `.ruby-version` に記載されたバージョンがまだrbenvでインストールされていない場合は警告ができるので、rbenvで追加すればOKです。



## これらを行うことによるメリット

以上で今回説明したいことは終わりです。

準備が大変な上にいろいろとインストールが必要になるのですが
`anyenv` + `bundler` で `CocoaPods` と `fastlane` を使うと以下のようなメリットがあります。

* `rbenv` + `.ruby-version` の設置 をすることでMacのRubyのバージョンに左右されずにCocoaPodsが使える
* チームで使っている `CocoaPods` のバージョンがマシンにインストールされたものと異なっていても大丈夫
* バージョン管理システムで `Gemfile` を管理することにより、ドキュメントなどに起こさなくても `CocoaPods` のバージョンを共有できる
* fastlaneの設定ファイルだけではなく、実行するfastlaneのバージョンを共有することができる

**envがいれるのが大変…というのであれば
bundlerを導入するだけでも、バージョン差異によるエラーには悩まされることはなくなるので
部分的にでも活用いただき、誰かの悩みのタネが減れば幸いです。

## 関連リンク
* [anyenvで開発環境を整える](https://qiita.com/luckypool/items/f1e756e9d3e9786ad9ea)
* [チームメンバーで利用するrubyのバージョンを共通化するときは\.ruby\-versionファイルを置くと便利 \- コード日進月歩](http://shinkufencer.hateblo.jp/entry/2018/08/08/234557)
* [rbenv \| global と local と \.ruby\-version の微妙な関係 \- Qiita](https://qiita.com/Yinaura/items/0b021984bb21ae77816d)
* [MacにHomeBrew,rbenv,bundlerをインストールする](https://qiita.com/shinkuFencer/items/3679cfd966f6a61ccd1b)
* [bundler で cocoapods そのもののバージョン管理をする](https://qiita.com/shinkuFencer/items/821501cd0c5c460c1fea)
* [CocoaPods Guides \- The Podfile](https://guides.cocoapods.org/using/the-podfile.html)
* [fastlaneの簡単な紹介と使用例 \- Septeni Engineer's Blog](http://labs.septeni.co.jp/entry/2016/09/14/162643)
* [これから始めるfastlane](https://qiita.com/econa77/items/d81a392d6b195cfb7316)
* [fastlaneの使い方を自分で調べられるための手引き \- rikusouda’s blog](http://rikusouda.hatenadiary.com/entry/2017/10/07/142449)