SIの現場のiOSアプリケーション開発

どうも、SIerのシステムエンジニアです。

[システムエンジニア Advent Calendar 2016](http://qiita.com/advent-calendar/2016/se)の11日目です。
10日目は [deaf_tadashi](http://qiita.com/deaf_tadashi)さんの「[聞こえないシステムエンジニアが心がけていること](http://qiita.com/deaf_tadashi/items/8079b10bfbe8e63eb069)」でした。

## はじめに

直近は金融系の新サービスのバックエンド側の開発をしていました。
会社で利用する言語はほとんどJavaで、iOSだとObjective-Cを遊び程度でさわったことがある程度です。

現在チームメンバーは5人で、スクラムで開発を進めています。
※ 厳密には[ふつうの受託開発のやりかた](https://github.com/kawasima/rascal-scheme) をチームに合わせて拡張したものです

ほとんど経験の無いiOSアプリケーション開発をいきなり任されたので、基本的には以下のような方針で物事を決めています。

* 世の中で実績があること
  * アーリーアダプターしか触っていないようなものは避ける
* ある程度安定していること
* とはいえ新しい技術であること
  * 社内にノウハウを溜めたい
* 転んでも大怪我しなさそうなこと
  * 代替手段があるなど

良い機会なので、SIの現場でiOSアプリケーション開発をするうえで採用したもろもろをまとめてみました。
経験値が少ないので、そうゆう場合はこうした方が良いよ！とか、こっちの方がオススメだよ！などあれば、コメントお願いします😇

## iOSバージョン

iOSは10以上のみターゲットにしています。
新規でしがらみもなく、試行的な位置づけなので対象を絞って開発をしています。
今後バージョンを広げていくこともありそうなので、情報収集とノウハウを貯めることが課題です。

## 開発言語

Swift 3を採用しました。
Swift 2の方がまだ書籍や情報が多いので悩ましかったのですが、Swift 3で大幅にAPIが変わっており、Swift 4では後方互換性を大事にするとアナウンスされているので、今後を考えてSwift 3を選択しました。

Swift 3 - Swift 4の話は、以下の記事がとても参考になりました。

* [Swift 3の開発の振り返りとSwift 4の計画が記されたメールの紹介 \- Qiita](http://qiita.com/mono0926/items/c51b74fae679e1e39d2b)

将来的にはAndroidも…という話しも考えられるので、[Apache Cordova](https://cordova.apache.org/)や[React Native](https://facebook.github.io/react-native/)、[Xamarin](https://www.xamarin.com/)なども調べましたが、Cordovaは作ろうとしているものの性質と合わなかったので採用見送り、React NativeとXamarinは、そもそもiOS SDKについての知識が少ないのに、プラスでReact Native + Reactや、Xamarin + C#　などを学ぶのは厳しいので採用を見送りました。

また、React Nativeは2016/12/11時点でバージョンが1.0に到達していないため、SIでの採用はまだ怖いな、というところもあります。

ただ、2016/11発表のThoughtWorksのTechnology RadarでReact.jsとReduxはADOPT扱い、React NativeはTRIALなので、これから採用が増えてくるのではないでしょうか。

![Languages_And_Frameworks___Technology_Radar___ThoughtWorks.png](https://qiita-image-store.s3.amazonaws.com/0/6092/970b3218-cfe9-10a7-7891-dc0b94535e7a.png)
[TECHNOLOGY RADAR NOV '16](https://www.thoughtworks.com/radar/languages-and-frameworks)

React × Redux(無くても良いですが) を普段から使い慣れており、iOSやAndroid向けにアプリを作らなきゃいけない、みたいな場合(両方の条件が揃うことはSIではなかなか無さそうですが)はマッチすると思います。
プラットフォームが更に増え、Web、Android、iOS、PC向けに開発して欲しいと言われた場合は、ロジックの共通化などでコスト、運用面でメリットがあるため、PoCなどを行った上で導入を検討しても良さそうです。

* [ReactとReact Nativeでコードを共通化し，web / android / iOS \(\+PC\)クロスデバイス開発 \- Qiita](http://qiita.com/yuichiroTCY/items/7c66691fe6cc244053de)

## 開発環境

全体像は以下のような感じです。実際はMac上にJenkinsとチャット類、GitBucketとRedmineは別サーバといった感じの構成になっています。
Rocket.chatとHubotは[Dockerで構築](http://qiita.com/tenten0213/items/5746d0fd27a7970742bf)しています。今では2年目のエンジニアがdocker-composeのコマンドを叩いていたりするので、こういったプロダクション以外の環境で新しい技術を採用すると成長の機会になります。

![dev.png](https://qiita-image-store.s3.amazonaws.com/0/6092/cfcaef2e-f996-d125-a024-e373c9a3a783.png)

### ITS

ITSはRedmineを利用しています。
[redmine\_backlogs](https://github.com/backlogs/redmine_backlogs)プラグインを追加し、バックログとかんばんで開発するユーザーストーリーやタスクを管理しています。

また、ノウハウやチームの決まりごと、スプリント毎のふりかえりの写真、スプリント計画の議事録などをRedmineのWikiに残すようにしています。(WikiはMarkdownで書けるようにしています)

### SCM

SCMには[GitBucket](https://github.com/gitbucket/gitbucket)を利用しています。ホント導入が楽で良いです。
前のプロジェクトでも前の前のプロジェクトでも利用しており、全社的にかなり利用されている気がします。

デフォルトの設定だと[Xcodeからpushができなかった](http://qiita.com/tenten0213/items/21c47f432b51e8da5866)ので、sshでも利用できるように設定を変更しています。

金融系のプロジェクト性質上、外部のサービスにソースコードを置くことが難しいので、自社のサーバを利用しています。費用の調整が付く場合はBitBucketを自社のサーバに入れて利用することもあります。

ブランチングモデルは、[GitHub Flow](http://scottchacon.com/2011/08/31/github-flow.html)に近いモデルを採用しています。(まだ出来ていないですが、マージしたらTest Flightにアップロードくらいまではやりたい)

直近のプロジェクトでは [git-flow](http://nvie.com/posts/a-successful-git-branching-model/) を採用していましたが、今回のコンテキストでは重すぎるので、GitHub Flowにしています。

### CI

CI用のMacを用意し、そこでJenkinsを動かしています。

Bundlerでgemを取得してきて[CocoaPods](https://cocoapods.org/)で依存関係の解決、[fastlane](https://github.com/fastlane/fastlane)でビルド、[SwiftLint](https://github.com/realm/SwiftLint)の実行、テストの実行とカバレッジの取得をしています。
上述したように、まだTest Flightへのアップロードなどは出来ていないので、今後の課題として取り組んでいこうと思っています。

金融系のプロジェクトなので性質上外部のCIサービスを利用することが難しいので、オンプレに導入できるものも調べました。

調べてみるとCircleCIが[CircleCI Enterprise](https://circleci.com/enterprise/)というものをやっていて、オンプレのサーバでも利用できるようです。金銭的な調整が面倒であまり真面目に検討しませんでしたが、CircleCIに任せられるのは楽なので、次回以降要検討かなと思っているところです。

* [Building iOS with CircleCI Enterprise \- CircleCI](https://circleci.com/docs/enterprise/ios/)
* [価格](https://circleci.com/pricing/#build-os-x)

### チャット

チャットは[Rocket\.Chat](https://github.com/RocketChat/Rocket.Chat)を利用しています。
ここも同様に、Slackとか使えないのでMac上にDockerで構築しました。

![](https://qiita-image-store.s3.amazonaws.com/0/6092/51c321d0-ddc8-161e-2e2a-e80b965e0ba6.png)

チャットでは各メンバ用のルームを用意し、現在やっていることを垂れ流すようにしてもらっています。

たまに何やってるんだろう？って他メンバーのルームを見たり、やっている内容にコメントを残したりしています。
また、タスクの完了や、課題を乗り越えた際に積極的に👍　を付けるようにしています。

分からないことがあれば、全員各メンバのルームに参加しているので、メンションを飛ばして質問することも可能です。

Hubotは入れるだけ入れたのですが、あまり時間が取れておらずスクリプトを整えられていません。
朝会の時間と持ち回りの司会者の通知、ビルド結果の通知あたりは早めに作りたいと思っています。
若いメンバーが多いので、ちょっとしたお題を出してスクリプトを書いてもらうのも勉強に良いかなと思っています。

## ソフトウェアアーキテクチャ

Clean Architectureに近いアーキテクチャを採用しています。
現在は小さいアプリケーションなのですが、将来的に結構な規模になりそうな話しもあり、保守性が高く、きちんとレイヤ分けされたアーキテクチャを採用しました。
メンバも普段Javaでレイヤを意識した設計のもとで開発をしてきているので、あまり自由度が高すぎるよりは良さそうな印象を受けました。

![https://8thlight.com/blog/assets/posts/2012-08-13-the-clean-architecture/CleanArchitecture-8b00a9d7e2543fa9ca76b81b05066629.jpg](https://8thlight.com/blog/assets/posts/2012-08-13-the-clean-architecture/CleanArchitecture-8b00a9d7e2543fa9ca76b81b05066629.jpg)
[The Clean Architecture \| 8th Light](https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html)

とはいえ、作成するクラスがMVCより多くなりがちなのと、それぞれのコンポーネントの関連を理解するのに時間がかかるのは確かなので、規模や今後の展望を鑑みて採用した方が良さそうです。

また、メンバーのスキル差がかなりあるので、Swift経験のあるメンバーにサンプルを作成してもらい、全員の理解を深めるようにしてから進めるようにしました。

ちなみに並行してホントに小さなアプリケーションの開発も行っているのですが、そっちはMVCで十分だと判断してMVCにしています。後述しますが、ライブラリもほとんど利用していません。

## 設計

バックログにあるユーザーストーリーに対してロバストネス図を作成するようにしています。

この段階で、どんなインタフェースがあるのか、イベントがあるのか、エンティティがあるのかを洗い出します。

![](https://www.ogis-ri.co.jp/otc/swec/process/am-res/am/images/models/robustnessDiagram.jpg)
[ロバストネス図の概要](https://www.ogis-ri.co.jp/otc/swec/process/am-res/am/artifacts/robustnessDiagram.html)

ロバストネス図は以下の3つの要素(+ アクター)で記述します。
シンプルで書きやすいのと、バウンダリは画面や外部システムとのインタフェース、コントロールは業務ロジック、エンティティはドメインモデルに紐づくので、設計に落とし込んでいきやすいです。

* バウンダリ
* コントロール
* エンティティ

### 設計書

SIerといえばExcel方眼紙な設計書がイメージされがちですが、フォーマットなんて瑣末な問題で、しっかりと設計することが重要です。(設計書を作る、になりがちなので注意が必要です)

私のチームでは、Markdownで設計書を書くようにしています。基本的にMacで仕事を進めていくことになるので、ExcelではなくMarkdownを採用しました。
お客様に説明するときは[PandocというツールでWordもしくはPDFに変換してから](http://qiita.com/tenten0213/items/f67f5601cbed6ef86b3c) 送付したり印刷したりしています。

また、MarkdownなのでGitで管理し、Pull Requestでレビューを行っています。
差分が見れて便利ですし、コメントで設計についての議論なども行えて良いです。

最初から完璧な設計を目指すというよりは、粗々設計してコードを書きつつ設計を改善していく、という流れで開発しています。

## ライブラリ

ライブラリはSwift 3に対応しているもので定番っぽい以下のライブラリを採用しています。

Quick + NimbleではなくXCTestでも良かったのですが(いわゆるxUnit系っぽい感じなのでメンバー的にも理解しやすそう)、ユーザーストーリーに対するテストを書きやすそうだったので採用しました。

* [Realm](https://realm.io/docs/swift/latest/)
* [Alamofire](https://github.com/Alamofire/Alamofire)
* [Bolts-Swift](https://github.com/BoltsFramework/Bolts-Swift)
* [Quick](https://github.com/Quick/Quick) + [Nimble](https://github.com/Quick/Nimble)

ライブラリの選定については、[@yimajo](http://qiita.com/yimajo)さんの以下の記事がとても参考になります。

* [今から新規でiOSアプリを書き始めるなら。2016年冬 \- Qiita](http://qiita.com/yimajo/items/5a7333fd709e625b60da)

今回は上記のライブラリを採用しましたが、有名なライブラリでもSwift 3への対応が出来ていないものも多く、全体的に大変そうな印象を受けました。

今回採用したライブラリを利用してみて、今後どうライブラリと向き合っていくのが良いか検討したいと思います。

## その他

ふだんはWindowsで仕事をすることが多く、社内の業務などはWindowsじゃないと困ることもあります。
そんなときはMacからWindowsにRDPしたり、WindowsからMacにVNCしたりして行き来しています。

別のビルに行って上司に報告・説明するときは、ミーティングスペースに置いてあるWindowsからWindowsにRDPして、RDP先の自分のWindowsからMacにVNCしてコードを見せたりなんかします。ややこしいですね。

* [WindowsマシンからMacにVNC接続する \- てんてんのぶろぐ](http://tenten0213.hatenablog.com/entry/2016/11/29/211656)
* [MacからWindowsマシンにRDPする \- てんてんのぶろぐ](http://tenten0213.hatenablog.com/entry/2016/11/14/123713)

![MacからWindowsマシンにRDPする \- てんてんのぶろぐ](https://cdn-ak.f.st-hatena.com/images/fotolife/t/tenten0213/20161114/20161114122909.png)

## まとめ

直近やっているiOSアプリケーション開発のモロモロをまとめてみました。

ちょっと前まではそれなりの規模で世の中に大きな影響を与えるようなプロジェクトに参画していて、今回はiOSアプリケーション開発。5年規模のプロジェクトに突っ込まれたこともありましたし(途中で自分に合わないから変えてもらったけど、優秀な人に囲まれて学びが多かった)、R&D部門で研究したり記事を書いたりもしていました。

SIerってプロジェクトが変わる度にやることが変わりますし、部門が変われば全然やることが変わります。
なので、社内を見渡すとすごい優秀な人がいっぱいいて飽きないです。

飽き性な人はSIer、オススメです。SIerはいいぞ。

----

次は12日目で、[@irof](https://twitter.com/irof) さんが担当です。
どんな記事が公開されるのか楽しみです。