Upgrade to Pro — share decks privately, control downloads, hide ads and more …

XcodeGenを利用したマルチモジュール化の取り組み / Multi-module approach using XcodeGen

XcodeGenを利用したマルチモジュール化の取り組み / Multi-module approach using XcodeGen

■イベント

【Sansan Technical View】Sansanの技術的「挑戦」
https://sansan.connpass.com/event/208003/

■登壇概要

タイトル:XcodeGenを利用したマルチモジュール化の取り組み

登壇者:Sansan事業部 プロダクト開発部 相川 健太

▼Sansan Builders Blog

https://buildersbox.corp-sansan.com/

13d936e697fe0f4fa96f926d0a712f6c?s=128

Sansan
PRO

May 28, 2021
Tweet

Transcript

  1. 0

  2. 相川 健太(Kenta Aikawa) 2020年2⽉に公⽴はこだて未来⼤学⼤学院を中退後、2020年4⽉に Sansan 株式会社に⼊社。在学時は主に Swift や Flutter を⽤いた

    iOSアプリの開発を⾏ったり、Ruby on Rails を⽤いた Web サイトの 開発を⾏っていた。⼊社後は iOS アプリケーションエンジニアとして 従事し、Sansan の iOS アプリの主要な機能開発や開発環境の改善に 取り組んでいる。 Sansan株式会社 Sansan事業部プロダクト開発部 iOSアプリケーションエンジニア 939_Aikawa_Kenta_bg_mono.jp g 1
  3. - Sansan iOS アプリについて - Sansan iOS アプリの紹介 - 2020年の

    Sansan iOS アプリの状態 - どのような状態が理想だったか - 理想の状態にするための取り組み - XcodeGen の導⼊ - Embedded Framework 化 - Embedded Framework 化時の Good・Problem - 学んだこと アジェンダ 2
  4. - Sansan iOS アプリについて - Sansan iOS アプリの紹介 - 2020年の

    Sansan iOS アプリの状態 - どのような状態が理想だったか - 理想の状態にするための取り組み - XcodeGen の導⼊ - Embedded Framework 化 - Embedded Framework 化時の Good・Problem - 学んだこと アジェンダ 3
  5. Sansan iOS アプリの紹介 4

  6. Sansan iOS アプリの紹介 5

  7. - Sansan iOS アプリについて - Sansan iOS アプリの紹介 - 2020年の

    Sansan iOS アプリの状態 - どのような状態が理想だったか - 理想の状態にするための取り組み - XcodeGen の導⼊ - Embedded Framework 化 - Embedded Framework 化時の Good・Problem - 学んだこと アジェンダ 6
  8. - 開発時のコンフリクト問題が増加していた - 開発メンバーの増加(約10名) - 機能追加のスピードも加速(現在は約100画⾯以上) - project.pbxproj のコンフリクト問題が特に顕著だった -

    ファイルの追加・削除などを⾏うだけで差分が出てしまうiOS アプリ開発者が 恐れるファイル - 通常ファイルのコンフリクトは⼤きな問題になりにくい - project.pbxproj は⼈が読めるような代物ではないことが難点 開発スピードの加速によるコンフリクトの増加 7
  9. - ファイル間の依存関係が不明瞭 - Swift は同モジュール内であれば import が不要なので、ファイル間の 依存関係が不明瞭になっていた > Sansan

    はほぼ全てのファイルが⼀つのモジュールに定義されていた - 「〇〇ディレクトリのファイルは△△ディレクトリのファイルに依存 させたくないが、依存してしまっている」状態が数多く発⽣していた - レガシーコードも数多く存在 - 現在は VIPER というアーキテクチャを採⽤しているが MVC 時代のディレクトリがいくつも残っている コードにも課題がいくつかあった 8
  10. - Sansan iOS アプリについて - Sansan iOS アプリの紹介 - 2020年の

    Sansan iOS アプリの状態 - どのような状態が理想だったか - 理想の状態にするための取り組み - XcodeGen の導⼊ - Embedded Framework 化 - Embedded Framework 化時の Good・Problem - 学んだこと アジェンダ 9
  11. - 理想の状態 1. project.pbxproj から脱却できている 2. ファイル間の依存関係が明確になっている 3. レガシーコードが撤廃・修正されている -

    解決⽅法 1. XcodeGen という project.pbxproj ⽣成ツールの利⽤ 2. Embedded Framework 化による import の強制 3. Embedded Framework 化を⾏う中で徐々に撤廃・修正 どのような状態が理想だったか 10
  12. - 理想の状態 1. project.pbxproj から脱却できている 2. ファイル間の依存関係が明確になっている 3. レガシーコードが撤廃・修正されている -

    解決⽅法 1. XcodeGen という project.pbxproj ⽣成ツールの利⽤ 2. Embedded Framework 化による import の強制 3. Embedded Framework 化を⾏う中で徐々に撤廃・修正 どのような状態が理想だったか 11
  13. - Sansan iOS アプリについて - Sansan iOS アプリの紹介 - 2020年の

    Sansan iOS アプリの状態 - どのような状態が理想だったか - 理想の状態にするための取り組み - XcodeGen の導⼊ - Embedded Framework 化 - Embedded Framework 化時の Good・Problem - 学んだこと アジェンダ 12
  14. - project.pbxproj のコンフリクト問題を解決する⽅法として有名な ツールの⼀つ - XcodeGen を⽤いることで project.pbxproj を冪等に⽣成することができる -

    つまり project.pbxproj を git 管理する必要がなくなる XcodeGen について 13
  15. XcodeGen の導⼊・利⽤⽅法 14 project.pbxproj XcodeGen project.yml

  16. XcodeGen の導⼊・利⽤⽅法 15 project.pbxproj XcodeGen project.yml

  17. - 現状はどうしても⼈の⼿で yml ファイルを作成することになる - yml の記法の学習コストが⽐較的⾼い - プロジェクトの規模が⼤きいほど yml

    の⾏数が多くなるため 導⼊が難しくなる(Sansan は約 600 ⾏) - プロジェクト⽴ち上がり初期などに XcodeGen を導⼊するとコスパが良い project.yml の作成難易度 16
  18. - ⾃分が⼊社する前から導⼊したいという話はあった - 以下のような理由から導⼊には踏み切れていなかった - メンバーの中に XcodeGen 導⼊経験者がおらず⼯数感が不明 - XcodeGen

    を導⼊することによって開発コストをどの程度 抑えることができるか不透明 XcodeGen 導⼊に⽴ち塞がる壁 17
  19. 導⼊までの道のり 個⼈的に勉強 案件で取り組み 無事 XcodeGen を導⼊ 開発の合間を⾒て yml を作成 18

  20. 導⼊までの道のり 案件で取り組み 無事 XcodeGen を導⼊ 開発の合間を⾒て yml を作成 19

  21. 導⼊までの道のり 案件で取り組み 無事 XcodeGen を導⼊ 開発の合間を⾒て yml を作成 20 時間・知識不⾜を

    痛感しながら yml と格闘
  22. - project.yml を作成する際には以下のような苦労があった - ドキュメント・記事をひたすら読んで yml 作成⽅法を学習 - 問題ないかどうかをレビュワーとすり合わせながらひたすら修正 project.yml

    との格闘 21 元の PJ 構成(左)と XcodeGen で⽣成した PJ 構成(右)をひたすら⽐較する作業 運⽤(上)・案件(下)で 取り組んでいた時の PR
  23. - ほぼ確実に発⽣していた project.pbxproj のコンフリクト問題が解消された - プロジェクトに関する全ての設定を yml ファイルで設定・確認 できるようになり、設定の変更も容易になった -

    後で詳しく説明する「Embedded Framework 化」の実現可能性にも寄与 XcodeGen 導⼊後の開発 22
  24. - Sansan iOS アプリについて - Sansan iOS アプリの紹介 - 2020年の

    Sansan iOS アプリの状態 - どのような状態が理想だったか - 理想の状態にするための取り組み - XcodeGen の導⼊ - Embedded Framework 化 - Embedded Framework 化時の Good・Problem - 学んだこと アジェンダ 23
  25. - Embedded Framework について - ファイルの集まりを Framework (モジュール)として分割する仕組み > リソースファイル(画像、Storyboard

    など)も格納できる > Dynamic Framework の⼀種 - Embedded Framework 化によるメリット > モジュール間の依存関係が明確になる(主にこれを期待) - 別 Framework のコードを呼び出す際は import が強制させられる > ビルド時間の短縮が期待できる - ビルド時間が 3 分ほどかかっている現状があるため、副次的な効果として期待 > ターゲットごとにテストを記述できるようになる Embedded Framework 化(マルチモジュール化) 24
  26. - Sansan iOS アプリについて - Sansan iOS アプリの紹介 - 2020年の

    Sansan iOS アプリの状態 - どのような状態が理想だったか - 理想の状態にするための取り組み - XcodeGen の導⼊ - Embedded Framework 化 - Embedded Framework 化時の Good・Problem - 学んだこと アジェンダ 25
  27. - Good - XcodeGen によって Embedded Framework 化が実現しやすくなっていた - Problem

    - Embedded Framework 化の進め⽅に問題があった - チームメンバー全員と共通認識を固めることができていなかった Embedded Framework 化時の Good・Problem 26
  28. - Good - XcodeGen によって Embedded Framework 化が実現しやすくなっていた - Problem

    - Embedded Framework 化の進め⽅に問題があった - チームメンバー全員と共通認識を固めることができていなかった Embedded Framework 化時の Good・Problem 27
  29. - XcodeGen によって各 Embedded Framework の「利⽤ファイル」・ 「設定」などは全てyml に記載すれば良いだけになっていた - XcodeGen

    を導⼊していない場合は Xcode 上で設定する必要がある - yml なのでコードレビューすることができる(コメントも残せる) Embedded Framework の定義を yml で完結させられる 28
  30. 複数種類ある Embedded Framework の共通設定部分を容易にまとめる ことができた Embedded Framework のメンテナンス性の向上 29

  31. 依存がある場合は yml 内の dependencies に記述する必要があるため、 Embedded Framework が依存している対象を明確にできた Embedded Framework

    間の依存関係の明確化 30
  32. - Good - XcodeGen によって Embedded Framework 化が実現しやすくなっていた - Problem

    - Embedded Framework 化の進め⽅に問題があった - チームメンバー全員と共通認識を固めることができていなかった Embedded Framework 化時の Good・Problem 31
  33. - ⽅針 - Embedded Framework 化しやすそうな部分からまずは⼿を付け、 後続の Embedded Framework 化に繋げる

    - Embedded Framework 化しやすそうだと考えていた部分 - Entity > API Response のフィールドだけが定義されているシンプルな構造体 - Utility > Utility という名前の通り便利なクラスなどが集まっている - API > API との通信処理、レスポンスのデコード処理などがまとめられている > 似ている役割のエンドポイントごとにファイルが分割されている 当時の Embedded Framework 化⽅針 32
  34. Embedded Framework 化の結果 - Entity - ある程度 EF 化することができた -

    レガシーコードに依存する部分は諦めた - Utility - 責務ごとにディレクトリを分割しながら EF 化した - API - レガシーな Model に依存していたため、 そもそも簡単には EF 化することができなかった 33
  35. - 「将来的にどのような状態が理想なのか」まで考えられていなかった - 理想形を考えていないと作業に迷いが⽣じる・チームも混乱させてしまう - 事前調査の不⾜によって作業途中に問題が発覚した - レガシーコードに依存している部分が多く、簡単に切り離せない - ディレクトリ内の全てが整理されているわけではない

    > 特に Utility(Utility という命名の時点で気づくべきだった) Embedded Framework 化の進め⽅で良くなかった点 34
  36. - Good - XcodeGen によって Embedded Framework 化が実現しやすくなっていた - Problem

    - Embedded Framework 化の進め⽅に問題があった - チームメンバー全員と共通認識を固めることができていなかった Embedded Framework 化時の Good・Problem 35
  37. - 開発中すり合わせを密に⾏うことができていたのは⾃分を含めて3名 - それ以外のメンバーには案件終了後に詳細を伝える形となってしまった - 全開発メンバーとすり合わせながら作業するべきだった - Embedded Framework を利⽤した開発スタイルに少なからず

    混乱が⽣じてしまっていた - ミーティングなどで共通認識を固めながら導⼊することが重要だった メンバーと EF に対する共通認識を固められていなかった 36
  38. - Sansan iOS アプリについて - Sansan iOS アプリの紹介 - 2020年の

    Sansan iOS アプリの状態 - どのような状態が理想だったか - 理想の状態にするための取り組み - XcodeGen の導⼊ - Embedded Framework 化 - Embedded Framework 化時の Good・Problem - 学んだこと アジェンダ 37
  39. - 最初の Embedded Framework 化は中途半端な結果に終わってしまった - しかし学べたことは多かった - アーキテクチャに関わる変更を⾏う場合 >

    変更のためにコードにどのような影響があるか具体的に考えること > 将来的にどのような状態が理想か考えること - 開発環境に⼤きな影響を与える変更を⾏う場合 > チームメンバーと共有を徐々に⾏いながら進めること > アイデア段階から共有しておくことが重要 学んだこと 38
  40. - 取り組んできたこと - XcodeGen の導⼊ > コンフリクト問題を解消できた > 設定値などを yml

    で管理できるようになった - Embedded Framework 化 > 結果としては、中途半端な状態で終わってしまった > しかし学べたことは数多くあった - Embedded Framework 化の実現⽅法 - アーキテクチャを変更するために必要な変更・理想形を考えることが重要 - アーキテクチャ・開発環境に⼤きな影響を与える場合は都度共有することが重要 > 今後は失敗を活かし、次以降の Embedded Framework 化に取り組んでいく予定 まとめ 39