ZOZOTOWNアプリHome画面再設計の軌跡~10年以上歴史を持つアプリはどのようにして生まれ変わったのか~

ogp

はじめに

こんにちは、ZOZOアプリ部でZOZOTOWN iOSアプリを開発している小松です(@tosh_3)。

気づけば、ZOZOテクノロジーズに新卒入社して1年が過ぎていました。オフィスの近くに引っ越したのですが、オフィスに出社する前に、オフィスが移転しました。

さて突然ですが、最近ZOZOTOWNに大きな変化があったことをみなさんお気づきでしょうか。2021年3月18日よりZOZOTOWN全体が大幅リニューアルされ、コスメモールがオープンされるなどの大きな変化がありました。アプリも7.0.0とメジャーバージョンの更新を行い、ほとんど全ての画面が新デザインになりました。

そこで、本記事ではHome画面のリニューアルを担当した私が、そこで使用した技術とその背景について触れながら、ZOZOTOWN iOSアプリのHome画面リニューアルの裏側をお伝えします。

ZOZOTOWNアプリの新旧デザイン比較

ZOZOTOWNのHome画面がどのくらい変わったのか、リニューアル前後のUIを比較してみましょう。

旧デザイン 新デザイン

黒ベースから白ベースへと変化し、よりモダンなデザインになっています。今まで、1つのページで構成されていたデザインは「すべて」「シューズ」「コスメ」と3つのタブの構成になりました。

Home画面のリアーキテクチャ

この改修をするにあたり、まずHome画面の再設計をするか否かを考えました。仮に再設計せず、既存のHome画面に新しい機能を追加していく場合、後述するHome画面が抱える潜在的な課題に遭遇する可能性が高くなります。開発の終盤で大きな変更を求められる課題に直面すると、スケジュール的にも場当たりな対応になりがちです。今までのZOZOTOWNアプリ開発の中でも似たようなシチュエーションが何度かありました。

また、再設計という選択肢を取った場合、QAチームによるフルリグレッションテストが必要になります。そのため、なかなか手軽に再設計をする判断をすることは難しいです。しかし、今回のケースでは再設計の有無に関わらず、どちららの選択をしてもQAではフルリグレッションテストを行う予定でした。以上の観点も踏まえると、再設計を行うには絶好の機会だったとも言えます。そのため、既存の課題の多くを救うためにも、再設計するという選択肢を取りました。

既存のHome画面が抱えていた課題

まず、既存のHome画面が抱えていた課題を紹介します。

  • 課題1. 改修すると様々な機能が影響範囲になる
    • ViewControllerが必要以上にたくさんの責務を担っており、改修に対して影響範囲が大きくなってしまう可能性が高かった
  • 課題2. Conflictの温床だった
    • Storyboardメインの開発が行われており、現在のiOSチーム構成(8人体制)の元では、Conflictが多発する原因になっていた

HomeViewControllerは数あるVCの中でも改修が多い対象であり、実際にプロジェクト内全てのVCの中で3番目にマージされた数が多かったです。

既存の課題解決へのアプローチ

前述の課題を解決するために、それぞれ以下のアプローチを取ることにしました。

  • 課題1. 改修すると様々な機能が影響範囲になる
    • 3タブ構成になることを踏まえて、HomeViewControllerの役割を再定義する
    • 疎結合かつ役割が明確になるようにクラスを定義する
  • 課題2. Conflictの温床だった
    • Storyboardベースからコードベースへと移行する

次に、疎結合とStoryboardの使用について説明していきます。

HomeViewControllerの整理

まず、既存のHomeViewControllerが持っていた役割を整理しました。

  • Home画面コンテンツの管理
  • Home画面コンテンツのAPI通信
  • Google Analytics(以下、GA)に関する機能
  • アプリのライフサイクルに関する機能
  • Home画面のライフサイクルに関する機能

これを見る限り、今までのHomeViewControllerはHome画面としての機能だけではなく、一番最初の画面としての機能も持っていました。結果として、HomeViewControllerは1400行以上にも及ぶFatViewControllerと化していました。

また、3タブ構成(すべて、シューズ、コスメ)へ変更すると、HomeViewControllerはさらに肥大化することが明らかです。そこで、HomeViewControllerの役割を再定義し、新しく各TabのViewControllerとLoggerクラスを作成しました。

それぞれの役割は以下の通りです。

HomeViewController

  • Home画面のタブの管理
  • アプリのライフサイクルに関する機能
  • Home画面のライフサイクルに関する機能

TabViewController

Home画面に存在する3つのタブ(すべて、シューズ、コスメ)をそれぞれ管理するViewController。

  • Home画面コンテンツの管理
  • Home画面コンテンツのAPI通信

Logger

  • GAに関する機能

以上のように、それぞれのクラスに明確な役割を持たせることで、3タブ構成に変更しても今までのコード量と同等で実装できます。

Storyboardを使用することは悪なのか?

StoryboardはConflictが多発する原因となっていましたが、「Storyboardを使用することはそんなに悪いことなのか?」と言われるとそうとは思いません。コードベースでUIを書くこと、StoryboardでUIを構築していくことそれぞれに良さがあります。

  • ZOZOTOWN iOSチームは現在8人体制で開発を行っている
  • 今後もチームのスケールアップを行う可能性が高い

このような環境では、Storyboardを使用するよりも、コードベースでUIを構築していくことの方が確実に向いていました。 他の画面では、Storyboardで多数のConflictが発生し、その度に手間がかかるということが多々発生している状態でした。ZOZOTOWNは10年以上の歴史を持つアプリなので、恐らくStoryboardで開発するのが向いていた時代もあったが今は向いていない、ただそれだけのことです。今回の改修では今までHome画面全体だけではなくUICollectionViewCellまでStoryboardで構成されていたものを、Home画面のHeader部分を除き全てコードベースへと変更することに成功しました。

Home画面のリインプリメンテーション

本章では、Home画面の再設計をどのように行ったのかを紹介します。

今回のリニューアルで実装したこと

Home再設計にあたり、以下の項目に挑戦しました。

  • Sandboxの作成
    • さまざまなパターンのHome画面をすぐに確認できるため、たくさんの試行錯誤が可能に
  • CompositionalLayoutの採用
    • 新デザインに柔軟に対応するために、CompositionalLayoutを採用
    • 適切なComponentへと切り出すことに成功
  • Storyboardの削除
    • Storyboardベースで設計されていた画面をコードベースへと移行
  • HomeViewControllerの疎結合化
    • GA用のクラスを別に切り出すなど、責任過多を解消
    • 1400行から600行に

本当は全ての内容を紹介をしたいのですが、本記事では特にCompositionalLayoutについて取り上げます。

CompositionalLayoutの採用

大幅なデザイン変更を行うということは、同時にHome画面で使用している技術を刷新する機会でもあります。また、チームとしても既存の部分とうまく結合できるのであれば、積極的に新しい技術に挑戦していく方針があります。そこで、ComopositionalLayoutを使用してみることにしました。CompositionalLayoutはWWDC19で紹介された機能です。続くWWDC20でも新たにCollectionViewListが強化されるなど、Appleとしてもここ数年はCollectionViewに力を入れていると感じていたので、是非機会があれば導入してみたいと考えていました。

なお、CompositionalLayoutとは、CollectionViewのレイアウト方法の1つであり、App Storeのようにセクションごとに異なるレイアウトを簡単に組むことのできる技術です。

引用: Layouts | Apple Developer Documentation

App Storeのようなカルーセルでも、FlowLayoutのカスタマイズや、中に別のCollectionViewを置くことなく容易にレイアウトを組めます。

さて、ここまでの説明を読みながら気になっていた方もいると思いますが、CompositionalLayoutが使用可能なのはiOS 13以上です。ZOZOTOWN iOSアプリは原則として3つの最新バージョンをサポートしており、当時サポートしていたOSはiOS 12、iOS 13、iOS 14でした。そのため、iOS 12でCompositionalLayoutをどのようにして使用するか、という問題に直面しました。

調べてみると、iOS 12でもCompositionalLayoutを使用可能にする、IBPCompositionalLayoutというライブラリがありました。そして、下記3点の理由からこのライブラリの導入を決めました。

  • ライブラリの作成者が弊社の技術顧問である岸川克己さんなので、何か困ったことがあった際にはいつでも相談できる
  • iOS 13以降では、純正のCompositionalLayoutを使用しており、iOS 12を切るタイミングではほとんど労力なく切り替えることができる
  • 弊社のWEARチームでも使用しているライブラリであり、社内での利用実績がある

このライブラリをZOZOTOWNで使ってみると、contentInsetAdjustmentBehaviorの値によってはうまく動かないパターンが見つかりました。原因を特定できたので、修正のPull Requestを出したため、現在では解消されています。ちなみに、このPull Requestで、初めてOSSにコントリビューションする実績をあげることができました。

github.com

CompositionalLayoutは、まだ新しい技術ということもあり、慣れるまではどのようにレイアウトを組むのが正解なのかわかりませんでした。そこで、技術検証を十分に行い、実装を進める上で疑問が生じた際には技術顧問の岸川克己さんにも相談に乗っていただきました。

実際に使用してみて感じた、CompositionalLayoutのメリット・デメリットを下記に挙げます。

メリット

  • App Storeのようなセクションごとに異なるレイアウトを組み合わせることが簡単な記述で実装できる
  • カルーセルの動きもサポートされている
  • カルーセル用のスクロールビューを自前で置く必要がない

デメリット

  • セクション内のスクロールビューの制御が必要になることにより、実装が難しくなる
  • ライブラリを使用しない限り、iOS 12以前のOSをサポートできない
  • OSによって挙動が若干異なり、一部OSでのみ発生するバグが存在する

個人的には、 今回、新たしい技術に挑戦してみて、確かに難易度が高い部分もありましたが、とても便利な機能だと感じました。是非このようなレイアウトを組む際には、検討してみるといいでしょう。

リザルト

課題とその解決法、そして技術的なアプローチを紹介してきました。それらを利用し、冒頭で紹介したZOZOTOWNが本質的に抱えていた課題をどのように解決したのか、一度まとめておきます。

  • 課題1. 改修すると様々な機能が影響範囲になる
    • 再設計する際に、疎結合にすることを意識し、役割ごとに明確なクラス分岐を行った
    • 1400行以上あったHomeViewControllerは役割が明確になり、600行ほどへ
  • 課題2. Conflictの温床だった
    • Storyboardの使用箇所を大幅に減らし、大部分をコードベースの設計へと変更した
    • その結果、Storyboardの制限に縛られることなくコード上で柔軟な分岐をすることが可能になった

今回の修正により、今後何か改修する際には、より少ない労力、かつ小さい影響範囲で対応できるようになりました。

リキャップ

再設計方法やその考え方に決して正解はありません。しかし、今回の再設計を通じ疎結合にすること積極的に新しい技術を検討していくことの重要性を再認識しました。また、技術選定をしていく中で、チームの状況とこれからを考えるという視点を持つ重要性にも新しく気づくことができました。

最後に

ZOZOテクノロジーズでは、一緒にモダンなサービス作りをしてくれる方を募集しています。ご興味のある方は、以下のリンクから是非ご応募ください!

tech.zozo.com

カテゴリー