ビジネスシーンで使えるメッセージングサービスSyncをローンチしました。
その開発の舞台裏をiOSを中心に紹介します。開発のスケジュール、リソース、アプリの規模や進め方など参考になれば幸いです。
サービスについて
Syncは社内・社外を問わずプロジェクトやビジネスコミュニケーションがより良い体験なることをゴールに開発しました。以下のURLよりご利用頂けます。
Web版 , Desktop版(OnlyOSX) , iPhone , Andorid
アーキテクチャ
サーバ
既存のWantedlyサーバに並列して、Syncのサービスをマイクロサービスアーキテクチャ風に構築しています。要素技術や構成はサービスの初期フェイズにおけるスピディーな開発とスモールな運用に適しているものを選定しています。
AccountServerが認証やユーザ情報管理を、APIServerが主要なデータのやり取りをREST形式で提供してます。共にRailsで構築しておりCookpadがOSSで提供している、RESTfulWebAPIを素早くパワフルに開発するためのライブラリGarageを採用しています。サーバはAPIのみ提供しておりHTMLをレンダリングするサーバはありません。
メッセージの送受信に必要なリアルタイム通信部分はFirebaseというGoogle傘下のPaaSを利用しています。リアルタイム通信をどのような要素技術を活用するかWebSocketやServer Sent Events(SSE)、LongPollingなどを検討した結果、Firebaseを選択しました。プッシュ系・プル系のリアルタイム配信では最新の更新情報を受領しても差分更新なのでクライアント側のデータ管理が大変になりがちです。Firebaseは内部ではWebSocketで通信していますが、そこがうまく隠蔽されサーバとクライアントのデータをリアルタイムで同期してくれるので管理の煩わすさから開放されます。またNode.js/Socket.IOなどで構築したサーバ群はスケールや運用を行うのはとても骨が折れますがPaaSなので運用面の負担も軽減できます。
- Account Server / Rails & Garage
- API Server / Rails & Garage
- Image Server / Sinatra & ImageMagick
- Realtime Server / Firebase
クライアント
クライアントはマルチプラットフォームに対応してサービスを提供しています。Web&Desktopはシングルページアプリケーション( AngularJS & Electron )で構築しています。Desktop版はWindows版が開発中でOSXのみ利用頂けます。iOSはSwiftの関数的な機能を活用して開発しています。 AndroidはJavaで開発しています。
- Web&Desktop / AngularJS v1.4, Electron
- iOS / Xcode6.4, Swift v1.2 iOS8〜
- Android / Android Studio v1.3.2, Android v4.0.3〜5.1.1
チーム
チーム編成は最大時で以下のような体制で常時フルコミットで参画してるのはそのうちの5名ほどです。iOSの体制が厚いので新規機能を率先して開発していました。
Product Owner & API Server
CTO @kawasy
Web & Desktop
Engineer @imaimiami / @creasty
iOS
Engineer @susieyy / @morizotter / @smztko / Designer @ferasyasin@github
Android
Engineer @cattaka / Designer @yanAoym
fastlane
Engineer @hedjirog
スケジュール(iOS)
サービスの開発は5月からスタートしiOSは3ヶ月間で申請まで行いました。iOSの開発リソースは6人月ぐらいです。最初の1ヶ月はプロトタイプ開発期間としてコードレビューもなく1人ででゴリゴリとコードを書きつつ、基本的な通信部分やMVVMアーキテクチャの実装、共通ロジックの用意などを行いました。本開発の始まった6月からは2名のエンジニアが追加となりプルリクエストのコードはレビューを行う体制で進めました。
進め方
上記のスケジュール図のようなざっくりな工程表と、要件一覧をもとにプロジェクトがスタートしました。2週間を1イテレーションとしてマイルストーンにタスクを入れてゆるいアジャイル風な運営で進めています。タスクをイテレーションの最初にある程度担当者にアサインはしつつも、進み具合でアサインを変更したり、マイルストーン間のタスクのを入れ替えたりと臨機応変さとスピード感を重視しています。実装を進めていく中で当初計画の要件に対してフィードバックを元に大きく機能を追加したり、実装済みでも大きく機能を削ったりと、より良い体験を作り上げることをゴールにドラスティックな変更を行いつつ開発しました。
ミーティングを必要最低限に抑えることでコーディングの時間をより多く確保しました。実装が始まる前の要件定義の段階で集中的にミーティングを重ねプロトタイプやデモを作って認識を合わせつつサービスの具体的なイメージをしっかり共有しました。実装の具体的な個々の仕様については、GitHubイシュー上で非同期で行い議論の証跡と結論や次のアクションを明文化しました。
ドッグフーディングとユーザフィードバック
ドッグフーディング(Dogfooding)とは、自社サービスを開発者自らが日常的に利用して問題点を早期に発見したりユーザー視点で品質やUXを確認することです。
開発開始から2週間でチームで利用していたSlackから乗り換えることを目標にしました。自分たちから積極的に利用することで開発者である自分たちからまずファンになることを大事にしました。1ヶ月ごろから社内の他のチームもSlackから乗り換えてもらい、たくさんのフィードバックを受けて安定性の向上と改善に勤めました。社内で実績を築いたことで2ヶ月ごろから身近な社外の方々にも声をかけて使ってもらい、さらに多くのフィードバックを頂きました。
メトリクス(iOS)
2015/09/05 時点です。開始からだいたい4ヶ月(80営業日ぐらい)ほど経過しています。
Github上の主要なメトリクス
プルリクエストはできるだけ小さい単位で送り合ってコンフリクト軽減とコードレビューしやすいように工夫をしています。プルリクエストがほとんどないプロトタイプ期間を省くと1日平均18件ぐらいになります。仕様やタスク、バグレポートなど明文化するものはすべてGitHubのイシューにして情報をすべてリポジトリ内で一元的に管理しています。すべてのプロジェクト情報がGitHub内ある、GitHub探せば見つかる状態を作っています。
- 4,700 Commits
- 1,050 Pull Requests Closed
- 864 Isusses Closed 83 Open ( Total 947 )
イシューの内訳です。Bugのイシューが一番多いです。Feedbackはローンチ前にTestFlightとFabricBetaで社内外に配布して使ってもらったフィードバックの数です。
- Improve 289 (30%)
- Bug 492 (51%)
- Feedback 64 (7%)
- Other(メモ、仕様、アイデアetc) 102 (12%)
コードステップ数(iOS)
Swiftのコードが141ファイル、1万9千行ほどですがフルコンパイルにPodsライブラリも合わせて4分!!ほどかかります。
$ cloc
288 text files.
285 unique files.
74 files ignored.
http://cloc.sourceforge.net v 1.64 T=1.36 s (157.4 files/s, 18819.8 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Swift 141 3157 1698 18708
JSON 66 0 0 1488
Objective C 3 90 116 212
C/C++ Header 4 28 27 63
-------------------------------------------------------------------------------
SUM: 214 3275 1841 20471
-------------------------------------------------------------------------------
画面数
ViewControllerは平均300行(空行なし)なので、ViewControllerだけで1万2千行になり全体の64%になります。ストーリーボードのファイルはコンフリクトしやすく1つのファイルにたくさんの画面を作成すると非常に遅くなるので細かく分割しています。
- 約25画面
- 42 ViewControllers
- 23 Storyboards
ライブラリ数
Swiftの機能を活かしたライブラリを積極的に取り入れています。SwiftライブラリをCocoaPodsでインストールすると、コンパイル時間が長くなるので事前にフレームワークを作成できるCarthageも利用しています。
Swiftコンパイル時間
MacBookPro (15-inch, Late 2013)でフルコンパイル時間が4分以上もかかっていたので以下の施策を行いました。
MacBookProを2台体制で開発する
レビューなどでブランチを切り替えると、Podsのインストールや、フルコンパイルが必要だったりするので2台体制で行いました。コンパイル時間も長かったので、待ち時間の有効活用に繋がり効率的に開発を進めることができました。
写真に写っている @morizotter はUSキーボードと日本語キーボードのMacBookProを使い分けています。脳内のスイッチングコストが高いと思うのですが流石です。
コンパイル時間を短縮する
4分以上コンパイルに必要になったころから、コンパイル時間の短縮化を行いました。4分10秒からー80秒の2分50秒になりました。
- 型推論しないで型を明記する (ArrayやDictionaryも)
- 複数のswiftファイルを一つにまとめる (importモジュールの解釈の回数を減らせます)
- 継承しないclassはfinalを明記する
- Cartage対応のライブラリはPodsでインストールしない
fastlane(iOS)
fastlaneを活用してビルド、テスト、配布までの工程を自動化しました。プルリクエストがレビューされマスターにマージされる度に自動で配布されます。常に最新のマスターの状態のリリースビルドを手元で常に確認できるようになりました。また配布が容易になることで、社内へのドッグフーディング、社外へのユーザフィードバックなどローンチ前にたくさんの方に使ってもらいやすくなりました。
マージマスターの配布はエンジニアとテスターに留め、ある程度安定していることを確認してから2,3日に一度社内外へ配布していました。
まとめ
このような背景で作られたサービスがどんなのか気になってくれ方是非使ってみてください!
- Syncについて
- Web版
- Desktop版(OnlyOSX)
- Windows版は開発中です
- iPhone
- Andorid