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

機械的なコーディングの自動化

 機械的なコーディングの自動化

After iOSDC Japan 2021 での登壇資料となります。

発表概要
https://zozotech-inc.connpass.com/event/222423/

以下、スライド内に登場するリンク一覧です。

大規模リファクタリングの極意
https://speakerdeck.com/imairi/da-gui-mo-rihuakutaringufalseji-yi

SourceKitten
https://github.com/jpsim/SourceKitten

RIBsCodeGen
https://github.com/imairi/RIBsCodeGen

Source Editor ExtensionとSwiftSyntaxでコード自動生成ツールを作る
https://fortee.jp/iosdc-japan-2021/proposal/734e9f50-1662-4aea-acc3-da4140a47dbd

タクシーアプリ GO の iOS エンジニア採用ページ
https://hrmos.co/pages/mo-t/jobs/2100002

Yosuke Imairi

October 06, 2021
Tweet

More Decks by Yosuke Imairi

Other Decks in Technology

Transcript

  1. Mobility Technologies Co., Ltd. 2 Yosuke Imairi ⾃⼰紹介 - JapanTaxi

    (2017.05 - 2020.4) - 全国タクシー - 相乗りタクシー - JapanTaxi - Mobility Technologies (2020.4 - ) - MOV - GO
  2. Mobility Technologies Co., Ltd. 5 設計から実装をはじめるまで 設計 実装 ❏ 要求をどう実現していくかを検討する

    ❏ 既存の実装の影響範囲を模索 ❏ 新しく必要なコンポーネントの役割は何か ❏ どういう段取りで作業を進めるのか ❏ ルーティング ❏ ビジネスロジックの実装 ❏ UI の作成
  3. Mobility Technologies Co., Ltd. 6 設計から実装をはじめるまで 設計 実装 実装の準備 ❏

    要求をどう実現していくかを検討する ❏ 既存の実装の影響範囲を模索 ❏ 新しく必要なコンポーネントの役割は何か ❏ どういう段取りで作業を進めるのか ❏ ルーティング ❏ ビジネスロジックの実装 ❏ UI の作成
  4. Mobility Technologies Co., Ltd. 7 設計から実装をはじめるまで(タクシーアプリ『GO』の場合) 設計 実装 実装の準備 ❏

    親 Interactable に⼦ Listener の追加 ❏ 親 Router に⼦ Builder の定義を追加 ❏ 親 Router のイニシャライズに⼦ Builder を追加 ❏ 必要であればイニシャライズの override を削除 ❏ 親 Router が保持する⼦ Builder の初期化 既存のRouter 既存のBuilder ❏ 親 Dependency に⼦ Dependency を追加 ❏ 親 Builder の build メソッド内で⼦ Builder を初期化 ❏ 親 Router ⽣成時に引数として⼦ Builder を追加 既存コードの改変(初期化, Protocol 追加などの単純作業) Router Builder Interactor ViewController Component Extension RIBs アーキテクチャで必要なボイラープレートの作成
  5. Mobility Technologies Co., Ltd. 8 設計から実装をはじめるまで(タクシーアプリ『GO』の場合) 設計 実装 実装の準備 ❏

    親 Interactable に⼦ Listener の追加 ❏ 親 Router に⼦ Builder の定義を追加 ❏ 親 Router のイニシャライズに⼦ Builder を追加 ❏ 必要であればイニシャライズの override を削除 ❏ 親 Router が保持する⼦ Builder の初期化 既存のRouter 既存のBuilder ❏ 親 Dependency に⼦ Dependency を追加 ❏ 親 Builder の build メソッド内で⼦ Builder を初期化 ❏ 親 Router ⽣成時に引数として⼦ Builder を追加 既存コードの改変(初期化, Protocol 追加などの単純作業) Router Builder Interactor ViewController Component Extension RIBs アーキテクチャで必要なボイラープレートの作成 ある程度決まりきった 単純な作業の繰り返し 🤔
  6. Mobility Technologies Co., Ltd. 9 設計から実装をはじめるまで(タクシーアプリ『GO』の場合) 設計 実装 実装の準備 ❏

    親 Interactable に⼦ Listener の追加 ❏ 親 Router に⼦ Builder の定義を追加 ❏ 親 Router のイニシャライズに⼦ Builder を追加 ❏ 必要であればイニシャライズの override を削除 ❏ 親 Router が保持する⼦ Builder の初期化 既存のRouter 既存のBuilder ❏ 親 Dependency に⼦ Dependency を追加 ❏ 親 Builder の build メソッド内で⼦ Builder を初期化 ❏ 親 Router ⽣成時に引数として⼦ Builder を追加 既存コードの改変(初期化, Protocol 追加などの単純作業) Router Builder Interactor ViewController Component Extension RIBs アーキテクチャで必要なボイラープレートの作成 機械的なコーディングは なるべく⾃動化したい 😲 💡
  7. Mobility Technologies Co., Ltd. 10 設計から実装をはじめるまで(タクシーアプリ『GO』の場合) 設計 実装 実装の準備 ❏

    親 Interactable に⼦ Listener の追加 ❏ 親 Router に⼦ Builder の定義を追加 ❏ 親 Router のイニシャライズに⼦ Builder を追加 ❏ 必要であればイニシャライズの override を削除 ❏ 親 Router が保持する⼦ Builder の初期化 既存のRouter 既存のBuilder ❏ 親 Dependency に⼦ Dependency を追加 ❏ 親 Builder の build メソッド内で⼦ Builder を初期化 ❏ 親 Router ⽣成時に引数として⼦ Builder を追加 既存コードの改変(初期化, Protocol 追加などの単純作業) Router Builder Interactor ViewController Component Extension RIBs アーキテクチャで必要なボイラープレートの作成
  8. Mobility Technologies Co., Ltd. 11 ボイラープレートへの対応策 ❏ Xcode Template ❏

    ~/Library/Developer/Xcode/Templates/File¥ Templates/ 内で管理
  9. Mobility Technologies Co., Ltd. 12 ボイラープレートへの対応策 ❏ Xcode Template ❏

    テンプレートにしたがって新規ファイルが作成される
  10. Mobility Technologies Co., Ltd. 13 設計から実装をはじめるまで(タクシーアプリ『GO』の場合) 設計 実装 実装の準備 Router

    Builder Interactor ViewController Component Extension RIBs アーキテクチャで必要なボイラープレートの作成 ❏ 親 Interactable に⼦ Listener の追加 ❏ 親 Router に⼦ Builder の定義を追加 ❏ 親 Router のイニシャライズに⼦ Builder を追加 ❏ 必要であればイニシャライズの override を削除 ❏ 親 Router が保持する⼦ Builder の初期化 既存のRouter 既存のBuilder ❏ 親 Dependency に⼦ Dependency を追加 ❏ 親 Builder の build メソッド内で⼦ Builder を初期化 ❏ 親 Router ⽣成時に引数として⼦ Builder を追加 既存コードの改変(初期化, Protocol 追加などの単純作業)
  11. Mobility Technologies Co., Ltd. ❏ RIBs における Router の場合 14

    既存コードをどう改変したいのか 特定の Protocol に準拠させる もし override があれば削除 新しいプロパティの追加 新しく追加したプロパティの初期化
  12. Mobility Technologies Co., Ltd. 15 既存コードの改変への対応策 ❏ 追加したいコードは決まっている ❏ 挿⼊箇所が特定できるとよさそう

    ❏ ファイルの⽂頭からの offset など ❏ コードの静的解析を活⽤ ❏ SourceKitten (SourceKit) ❏ SwiftSyntax (swiftc -frontend -emit-syntax)
  13. Mobility Technologies Co., Ltd. 特定の Protocol に準拠させる もし override があれば削除

    新しいプロパティの追加 ❏ offset, length を組み合わせることで任意の場所にコードを挿⼊できる 26 既存コードを改変する 新しく追加したプロパティの初期化
  14. Mobility Technologies Co., Ltd. 特定の Protocol に準拠させる もし override があれば削除

    新しいプロパティの追加 ❏ offset, length を組み合わせることで任意の場所にコードを挿⼊できる 27 既存コードを改変する Interactable の offset + length のあとに 「,」 追加 ⇒ 改⾏ ⇒ 特定の Protocol を挿⼊ init の offset の前に 改⾏ ⇒ プロパティを追加 init に override 修飾⼦がある場合は削除 新しく追加したプロパティの初期化 init の bodyOffset などから計算して 必要なプロパティの追加、初期化
  15. Mobility Technologies Co., Ltd. 28 SourceKitten でハマったところ 😅 ❏ offset,

    length で表現される数値は UTF-8 のバイト数 ❏ 改⾏コードもカウントされる
  16. Mobility Technologies Co., Ltd. 29 既存コードの改変を⼿助けするツールの作成 ❏ RIBsCodeGen ❏ https://github.com/imairi/RIBsCodeGen

    ❏ SourceKitten を利⽤したボイラープレート⾃動⽣成 + 依存解決ツール ❏ RIBs アーキテクチャにおける「実装準備」に必要な作業をすべて⾃動化 ❏ RIBs 利⽤者が⼿軽に利⽤できるよう Swift Package Manager として公開 ❏ Markdown 形式で設計を読み込ませることで⼀括処理が可能
  17. Mobility Technologies Co., Ltd. 31 ❏ コードを解析して地道に書き換えていく ❏ コマンドラインからの⼊⼒を受け付ける ❏

    該当のディレクトリ・ファイルの存在有無の確認 ❏ なければ作成しそのファイルパスを取得 ❏ ファイルパスから Swift コードを読み込み解析 ❏ 状態に応じて必要な処理を追加(書き込み) ❏ 特定のProtocol への準拠 ❏ 初期化の引数に特定のプロパティを追加 ❏ override 削除 ❏ コードの整形 CommandLine PathKit SourceKitten PathKit … etc. SourceKitten
  18. Mobility Technologies Co., Ltd. 32 設計から実装をはじめるまで(タクシーアプリ『GO』の場合) 設計 実装 実装の準備 ❏

    親 Interactable に⼦ Listener の追加 ❏ 親 Router に⼦ Builder の定義を追加 ❏ 親 Router のイニシャライズに⼦ Builder を追加 ❏ 必要であればイニシャライズの override を削除 ❏ 親 Router が保持する⼦ Builder の初期化 既存のRouter 既存のBuilder ❏ 親 Dependency に⼦ Dependency を追加 ❏ 親 Builder の build メソッド内で⼦ Builder を初期化 ❏ 親 Router ⽣成時に引数として⼦ Builder を追加 既存コードの改変(初期化, Protocol 追加などの単純作業) Router Builder Interactor ViewController Component Extension RIBs アーキテクチャで必要なボイラープレートの作成
  19. Mobility Technologies Co., Ltd. 33 設計から実装をはじめるまで(タクシーアプリ『GO』の場合) 設計 実装 実装の準備 ❏

    親 Interactable に⼦ Listener の追加 ❏ 親 Router に⼦ Builder の定義を追加 ❏ 親 Router のイニシャライズに⼦ Builder を追加 ❏ 必要であればイニシャライズの override を削除 ❏ 親 Router が保持する⼦ Builder の初期化 既存のRouter 既存のBuilder ❏ 親 Dependency に⼦ Dependency を追加 ❏ 親 Builder の build メソッド内で⼦ Builder を初期化 ❏ 親 Router ⽣成時に引数として⼦ Builder を追加 既存コードの改変(初期化, Protocol 追加などの単純作業) Router Builder Interactor ViewController Component Extension RIBs アーキテクチャで必要なボイラープレートの作成
  20. Mobility Technologies Co., Ltd. 34 設計から実装をはじめるまで(タクシーアプリ『GO』の場合) 設計 実装 実装の準備 ❏

    親 Interactable に⼦ Listener の追加 ❏ 親 Router に⼦ Builder の定義を追加 ❏ 親 Router のイニシャライズに⼦ Builder を追加 ❏ 必要であればイニシャライズの override を削除 ❏ 親 Router が保持する⼦ Builder の初期化 既存のRouter 既存のBuilder ❏ 親 Dependency に⼦ Dependency を追加 ❏ 親 Builder の build メソッド内で⼦ Builder を初期化 ❏ 親 Router ⽣成時に引数として⼦ Builder を追加 既存コードの改変(初期化, Protocol 追加などの単純作業) Router Builder Interactor ViewController Component Extension RIBs アーキテクチャで必要なボイラープレートの作成 設計が終わったら すぐに実装が開始できる 😊
  21. Mobility Technologies Co., Ltd. 35 まとめ ❏ 設計から実装開始までの作業は意外と多い ❏ ボイラープレートの作成

    ❏ 繰り返される機械的なコーディング ❏ 静的解析はツールを使えば難しくない ❏ SourceKitten / SwiftSyntax を利⽤してみる ❏ なるべく実装⾃体に時間を使えるように⼯夫したい ❏ 単純な作業は⾃動化して開発効率をあげよう ❏ iOSDC Japan 2021 にも関連トークがあるのでぜひ ❏ https://fortee.jp/iosdc-japan-2021/proposal/734e9f50-1662- 4aea-acc3-da4140a47dbd