iOS開発「VIPERアーキテクチャ」採用に使える「Generamba」の使い方とエラー対処法まとめ

Swift勉強会に参加した際に、アーキテクチャ設計は何を使っているのかをほかの開発者の方々に聞いていたら、
**「VIPERがいいよ！」**
教えてくれたので、早速使ってみることにしました。
その過程で、コード自動生成ツール**「Generamba」**とを使ったのですが、その際にエラーがいくつか出てきたのでその解決方法をご紹介します。

## VIPERとは？
VIPERは、MVCやMVVM、Clean Architectureなどのような、ソフトウェアアーキテクチャ手法の一つで、

**V:　  View**
**I:　　Interactor**
**P：　Presenter**
**E：　Entity**
**R：　Router**

から成っています。
詳しくはこちらの記事が最高に分かりやすかったです。
[iOS Project Architecture : Using VIPER [和訳]
](https://qiita.com/YKEI_mrn/items/67735d8ebc9a83fffd29)


## Generambaとは？
Generambaは、iOSアプリ開発向けにテンプレートに則ったコード生成を行なってくれるツールです。

[strongself/Generamba](https://github.com/strongself/Generamba)

VIPERやClean Architectureではファイル数が多くなりがちで、いちいちそれを生成するのが面倒になりますが、Generambaを使ってやれば、テンプレートから複数ファイルを自動生成してくれます。

## Generambaを導入する

### Generambaをインストールする
基本的には、公式のReadmeの通り進めていけばOKです。

`$ gem install generamba`

でOKです。
Gemが入っていない人はそちらのセットアップからやりましょう。

## Generamba Setup
続いて、アプリのプロジェクトのルートに移動し、
`$ generamba setup`
を行います。
すると、ターミナル上でいくつかの質問が出てくるので順に答えていきましょう。
私の場合、以下のように答えました。

```
The company name which will be used in the headers: my company
The name of your project is SampleApp. Do you want to use it? (yes/no) yes
The project prefix (if any):
The path to a .xcodeproj file of the project is 'SampleApp.xcodeproj'. Do you want to use it? (yes/no) yes
Select the appropriate target for adding your MODULES (type the index):
0. SampleApp
1. SampleAppTests
2. SampleAppUITests
 0
Are you using unit-tests in this project? (yes/no) yes
Select the appropriate target for adding your TESTS (type the index):
0. SampleApp
1. SampleAppTests
2. SampleAppUITests
 1
Do you want to add all your modules by one path? (yes/no) yes
Do you want to use the same paths for your files both in Xcode and the filesystem? (yes/no) yes
The default path for creating new modules: /SampleApp/Modules
The default path for creating tests: /SampleAppTests/Tests
Are you using Cocoapods? (yes/no) yes
The path to a Podfile is 'Podfile'. Do you want to use it? (yes/no) yes
Are you using Carthage? (yes/no) no
Do you want to add some well known templates to the Rambafile? (yes/no) yes

+--------------------+----------------------------------------------------------------------------------+
|                                      Summary for generamba setup                                      |
+--------------------+----------------------------------------------------------------------------------+
| company            |                                                                                  |
| project_name       | SampleApp                                                                        |
| prefix             |                                                                                  |
| xcodeproj_path     | SampleApp.xcodeproj                                                              |
| podfile_path       | Podfile                                                                          |
| templates          | ["{name: rviper_controller}", "{name: mvvm_controller}", "{name: swifty_viper}"] |
| project_target     | SampleApp                                                                        |
| project_file_path  | /SampleApp/Modules                                                               |
| project_group_path | /SampleApp/Modules                                                               |
| test_target        | SampleAppTests                                                                   |
| test_file_path     | /SampleAppTests/Tests                                                            |
| test_group_path    | /SampleAppTests/Tests                                                            |
+--------------------+----------------------------------------------------------------------------------+

Rambafile successfully created! Now run `generamba template install`.
```

**この時に私はエラーが発生しました。**
**対処法は、[「直面したエラーと対処法」](https://qiita.com/kenny_J_7/items/87c7e768ea7c44e39d42#%E7%9B%B4%E9%9D%A2%E3%81%97%E3%81%9F%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%A8%E5%AF%BE%E5%87%A6%E6%B3%95)を参照してください。**

以上でセットアップは完了です。

## Generamba Template Install

先ほどのセットアップの最後に出てきた通り、

`$ generamba template install`

を実行します。

すると、アプリプロジェクトのルートディレクトリに、`Templates`というフォルダが作成され、中にデフォルトのテンプレートとしてVIPERやMVVMなどのアーキテクチャ向けのテンプレートがインストールされます。

## Generamba Generate

VIPERでは基本的に**「１画面＝１Module」**となります。
Moduleをテンプレートで簡単に作成できます。

たとえば、Login画面のためのModuleを作ってみます。

`$ generamba gen Login swifty_viper`

最後の引数`swifty_viper`が利用するテンプレートです。
このテンプレートを自分でカスタマイズして新しく作ることもできます。

これを実行すると、`/Modules`にLoginフォルダが作成され、その中にVIPERに必要なファイルが作られていることがわかると思います。

以上が、GenerambaでのVIPER設計のやり方です。
次に、これらを実行する際に直面したエラーとその対応方法を紹介します。

## 直面したエラーと対処法
### "[Xcodeproj] Unknown object version. (RuntimeError)" エラー
**症状**
`$ generamba setup`
すると、以下のエラーが発生しました。

```
/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/xcodeproj-1.4.2/lib/xcodeproj/project.rb:217:in `initialize_from_file': [Xcodeproj] Unknown object version. (RuntimeError)
```
**対処法**
[こちら](https://github.com/strongself/Generamba/issues/203)に書いてある通り、下の画像のように、**Project Format**を**"Xcode 8.0-compatible"**に変更すると解決できます。

![alt](https://user-images.githubusercontent.com/34400829/42690284-479382b2-86ac-11e8-8335-050085da9d78.png)

**[注意]**
R.swiftを併用している場合、Project Formatを元に戻さないとR.generated.swiftが自動更新されない不具合を掴むことになりますので、適宜切り替えてください。


### "Xcodeproj doesn't know about the following attributes" エラー
**症状**
`$ generamba setup`
すると、以下のエラーが発生する。

```
[!] Xcodeproj doesn't know about the following attributes {"inp
utFileListPaths"=>[], "outputFileListPaths"=>[]} for the 'PBXShellScriptBuildPhase' isa. (RuntimeError)
```

**対処法**
[こちら](https://github.com/CocoaPods/CocoaPods/issues/7835#issuecomment-407428465)に書いてある通り、project.pbxprojをいじってやる必要があります。
![alt](https://user-images.githubusercontent.com/1257961/43145191-b9276cd8-8f56-11e8-826b-c4b0af66d330.png)

## 最後に
結構色々修正をしてやらないと、Generambaを使うことができずに面倒に感じましたが、この記事が誰かの役に立ってVIPERが広く浸透すれば嬉しいです。
ちなみに、GenerambaでデフォルトでインストールできるVIPERのテンプレートは少し使いにくかったので、オリジナルでカスタマイズをしてみました。
よければ参考にしてみてください。
[VIPER-Template](https://github.com/kentny/VIPER-Template/tree/master)