いい感じにiOSアプリ開発プロジェクトを立ち上げる方法を考える

f:id:laiso:20160718030202j:plain
pxhere.com*1

ここ数年、新規に開発するモバイルアプリのリードになる機会が何回かあり。プロジェクトの開始時期に毎度、README.md に開発方針を記述していたのだけど、いつも似たような内容になり公共性がありそうなのでそのままブログにした。

普段から「今回はアーキテクチャは何を採用しましょうか?」みたいな段階から議論がはじまるのを避けた方が建設的だと思っているので、その思想が反映されている。

想定する状況

我が社はこれからゼロからモバイルアプリを使ったサービスを提供するところであり、人手は少ないが開発初期段階から技術に投資する意気込みはあり、いずれはサービスの大ヒット、組織の大規模化を見据えて段階的に成長するアーキテクチャをバーンとやっていきたい。

事業領域は例えば決済サービスやビジネス系のモバイルアプリを想定している。

これは何?

iOSアプリのソフトウェア設計面についての現時点での考えを未来のメンバーに共有するための文書

基本方針

「ふつうのことを普通にやる」

ふつうとは—— ふつうの〇〇プログラミングというシリーズの良書があったり、Railsコミュニティなどでコンテキストとして利用されていたりする便利なイディオム。*2

僕の解釈では問題に対して多くの開発者が共通認識で選択する解決手法を採用すること。それによって環境要因や個人の嗜好によって偏りができるのを防ぐことができる。

なぜそうしたいのかというと、先の見えない開発なので技術的に凝ったことや挑戦に労力を使うよりプロダクトのUXに大きく寄与する部分に注力するため。技術的な挑戦がUXに直接的に関わる時は別。個人やチームの成長のための技術的投資は基本的にサイドプロジェクトでやることにしてる。

プロダクトの特性上、モバイルのアプリケーションの表面上でできる体験より。バックエンドのビジネスシステムの信頼性や運用にかかる効率化が価値となると考える。 (一方TikTokやインスタみたいな没入型の体験を提供するアプリケーションの開発に従事する人たちにはまた別の価値観があるのかもしれない)

決めたこと

  • React Nativeを使わない
    • 開発対象が素朴なUIを持つツールである。ドラゴンも出てこないしアイドルのライブ配信もない
    • ユーザーがKyashやメルカリみたいなものを期待するとギャップが生じガッカリさせてしまう
    • アップデート・保守面のコストが許容できない
    • PMF検証フェーズであり、クロスプラットフォーム提供の旨みがない。アーリーアダプタもほぼiOSユーザーと予想
  • RxSwift/MVVMでがんばらない
    • 「大いなる力には大いなる責任が伴う」 (意訳: 強い人は勝手にやってくれ)
    • 経験上FRPや宣言的View+データバイディングをがんばりはじめると、受け入れる複雑さがコードの保守性や品質向上にペイしないため
    • 非同期処理の問題解決のためだけに採用されるケースもある。将来のSwiftでasync/await世代の方法論が出てきた時のために、サードパーティ依存な部分を減らしたい
    • 小さく使う方法はあるのかもしれない。RxCocoaデータバインディングだけ抜き。とか。
  • Storyboardを利用。Feature単位でファイルを切る
    • 多人数開発ではないのでコンフリクトのリスクが低い
    • 標準コンポーネントを使って、デザイナ作業が不要である程度楽に開発が進む
  • 単体テストは書く
    • 状態管理フレームワークを検討するぐらい複雑なら必須!
    • TDDはがんばらずに、脳内でシュミレートして開発を促進させそうな部分だけ書く(自己判断)
    • CIサーバーの運用とかがんばらずに最初は手元で実行できればいい
    • 一方デプロイ自動化は今後何百回もやることがわかり切っているので最初からやる
    • モック化とかも考えずにE2Eになる部分がでてしまってもよい(むしろ設計に役立つ)
    • ドメイン/プレゼンテーション分離の設計を意識するため(あとからまとめてリファクタリングするのは難しい)

迷っていること

  • サーバーサイドとのデータやりとり
    • 受信のみ。送信のみ。双方向。リアルタイム性。などの性質を加味して検討してる
    • 巨大なHTTPライブラリ: Alamofireのようなものを採用するのか。範囲を絞って小さく使うのはありかもしれない
    • またはAPIKitの仕組み: ユーザーは少ないけど筋がいい
    • REST API: protobufやswagger-codegenみたいなものである程度自動生成するのか。実践したことないのでわからない
    • gRPC: サーバーがPaaSなど制限があると検討外になりそう
    • Firestore: 最近うまくいった(レイテンシ以外は) *3 APIクライアント層を書くかわりにサーバーエンジニアがCloud Functionsを書くことになりがち
    • AppSyncやApollo: GraphQLツール群次第