iOSアプリのUI開発を効率化する!

この記事は eureka Native Advent Calendar 8日目の記事です。

7日目は RxJava,Kotlin,Databindingでイケてる入力フォームをスッキリ実装するでした。

こんにちは!Pairs Global事業部の山中(@mtfum)です。

eureka Native Advent Calendar 2017 1日目の記事で少しだけ触れたModule分けについて、そのメリットを活かしたUI開発についてお話しします。

状態に依存したUIの開発は大変

特定の条件下でのみ表示されるUIを確認するために、プロダクションコード内でデモのためにダミーの値の変更を繰り返しながら開発した経験はありませんか?

例えば、「文字が改行されて全て表示されるかを確認」するために次のようなことを行ったり。

label.text = model.name
#if DEBUG
label.text = "ダミーダミーダミーダミーダミー..."
#endif
1回の確認で良いならこれでも充分なのですが、#if DEBUGで囲み忘れるとプロダクトに混入する可能性がありますし、プロダクションコード内にコメントアウトして残しておくのも良いアプローチとは言えません。
また、試すべきパターンの数が多い場合はどうでしょうか。
Pairsを例にすると、Pairsに登録したユーザーが持つ大まかな状態は次のとおりです。
  • 男性
  • 有料会員かどうか (Bool)
  • 2通り
  • プレミアムオプションを持っているかどうか (Bool)
  • 2通り
  • 年齢確認の状態 (enum)
  • 3通り
  • 年齢確認していない
  • 年齢確認中
  • 年齢確認が完了している
  • 女性
  • 年齢確認の状態 (enum)
  • 3通り
  • 年齢確認していない
  • 年齢確認中
  • 年齢確認が完了している
コードでは以下のように表現できます。
public enum Status {
case male(isPaid: Bool, isPremium: Bool, ageProofStatus: AgeProofStatus)
case female(ageProofStatus: AgeProofStatus)
}
ざっくり計算するとパターン分けは (2 * 2 * 3) + 3 = 15通りになります。
さらに、上記に加えてユーザーには様々な状態が付与されています。
このように、データが持つ状態の数が多いため、すべての状態を再現しつつ開発を進めていくのは大変です。
継続的な開発を行う際に試すべきケースはすぐに確認できるように用意しておきたいと考えました。
UIコンポーネントのデモを行うためのアプリを用意する
私たちは、状態に応じたUIコンポーネントのデモ・開発・確認を素早く行えるようにするために、Pairsアプリとは別で専用のアプリを用意し、UICatalogという名前で管理しています。
UICatalogを利用することでUIコンポーネントのプロトタイピングや改善と修正のサイクルを早めることが出来ます。
UICatalog.mov
見た目はかなり適当ですが、トップページには各UIコンポーネントのデモを行う画面へのメニューが表示されています。
UIコンポーネントごとにPlaygroundが用意されているイメージです。
PairsとUICatalogでは共通のModuleを使用する
Pairs.appとUICatalog.appのModule構成は次のようになっています。
  • 📦App.framework
  • 📄画面やUIコンポーネントのクラス
  • 📦その他のframeworkへの依存
  • 📱Pairs.app
  • 📄AppDelegate.swift
  • 📦 App.framework
  • 📱UICatalog.app
  • 📄 AppDelegate.swift
  • 📦 App.framework
Moduleに包んで共通化している理由は、ソースコードをTargetそれぞれに追加しても良いのですが、App.frameworkにしておくことで、PairsとUICatalogを切り替える際にApp.frameworkのキャッシュされたビルドが使え、再ビルドが走るのを防ぐメリットがあります。
また、UICatalogからは@testable import AppとすることでinternalのUIコンポーネントもUICatalogに呼び出せます。
最後に
Module分けのメリットを活かして、状態に依存したUIコンポーネントを開発しやすくする方法を紹介しました。
ただし、デモを簡単に行うためにはUIコンポーネント自体を外部から操作しやすい状態にしておく必要があります。
UIコンポーネントからの依存関係が多いとデモのためのダミーデータを作る手間が増えてしまいます。
そのため、UIコンポーネントの表示に必要な依存物を最小限かつ外部から注入可能(Dependency Injection)にするとよいでしょう。
開発効率化のアイデアの1つとしてヒントになれば嬉しいです。
ありがとうございました。
明日は丹さんRxSwiftにおけるマルチスレッドの理解を深める - Schedulerについてです!お楽しみに!
Like what you read? Give eureka_developers a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.