8年目iOSアプリにあたりまえを導入する

1.3K Views

October 07, 26

スライド概要

profile-image

Swiftを書いています

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

8年 iOSアプリに あたりまえを導 入 目 Ockey する

2.

Ockey ピクシブの25新卒で2年 2025/7にiOSアプリエンジニアとしてPalcyチームに配属 Palcy iOSチームリーダー 目 2

3.

Palcy ピクシブと講談社が協業で開発するマンガアプリ 2018/8にリリース 8周年、現在は9年 のアプリ 既存コードは UIKit + RxSwift + MVVM 目 ©株式会社講談社 3

4.

課題 4

5.

iOSチームの課題 • 複数 で開発するための仕組みがない • メンテや新機能の実装が難しい構造になっている • レビューコストが い • ドキュメントや意思決定の記録が全くない 高 人 5

6.

複数 で開発するための仕組みがない • フォーマッタがない • プロジェクト作成時のシングルモジュールのままなので、.pbxprojの コンフリクトが起きる • プルリク作成時にテストを実 していない 行 人 6

7.

メンテや新機能の実装が難しい構造になっている • シングルモジュールなので、 ‣ Previewの更新に1分〜かかる ‣ 依存関係を把握しにくい • iOS 16.0+なのでObservationを使えない • MVVMっぽいアーキテクチャだがVMのユニットテストがない 7

8.

レビューコストが い • アーキテクチャがハッキリしていない • コードスタイルがハッキリしていない • レビューで 針の違いが初めてわかる • 最終的にコミュニケーションコストが くなる 高 高 方 8

9.

ドキュメントや意思決定の記録が全くない • 既存のコードに対して「こうは書かないはず」と思ったとき、単に実装に 時間をかけられなかったのか、ワークアラウンドなのかわからない • Android版のコードを調べながら判断する必要があった • ドキュメントを作る余裕がない 9

10.

課題 アーキテクチャがハッキリしていない レビューコストが い 特にこれをどうにかしたい 当時8年 のアプリに、1年かけてあたりまえを導 してきた 入 高 目 10

11.

やったこと 1. フォーマッタの導 2. マルチモジュール化 3. アーキテクチャの体系化 4. CI/CD(Continuous Delivery)の整備 5. ADR(Any Decision Record)の整備 6. 新しいデザインへの対応 入 11

12.

やったこと 1. フォーマッタの導 2. マルチモジュール化 3. アーキテクチャの体系化 4. CI/CD(Continuous Delivery)の整備 5. ADR(Any Decision Record)の整備 6. 新しいデザインへの対応 今回は3つお話しします 入 12

13.

フォーマッタの導 入 13

14.

フォーマッタの導 |選択肢 フォーマッタ 実 タイミング • swiftlang/swift-format • ビルド時 • nicklockwood/SwiftFormat • commit直前 • push直前 組み込み • 任意のタイミングで 動実 • Homebrew • CIで実 して上書き • mint • パッケージに組み込む 入 行 手 方 行 行 14

15.

|選定 メリットよりデメリットに注 して選定した 選択肢に挙がる時点で、どれも きなメリットがある 度導 すると簡単には剥がせないので、デメリットに注 良いと判断した しておいた が 方 目 大 入 目 15 入 一 フォーマッタの導

16.

フォーマッタの導 |選定 swiftlang/swift-format • ルールが43個と少ない • 整形せずLintモードのみのルールがそこそこある nicklockwood/SwiftFormat • ルールが117個と多い • サードパーティー製である(が、継続的にメンテされており社内でも導 済み) → SwiftFormatを導 した 入 入 入 16

17.

フォーマッタの導 |結果 組み込み 、実 タイミング、ルールを選定し、理由までまとめることで 他メンバーがYes/Noを答えるだけで済むようにした 導 後「ここで改 したいです」のようなフォーマットに関するコメント がプルリクからなくなった →レビューコストを下げられた 入 行 行 方 入 17

18.

マルチモジュール化 18

19.

マルチモジュール化|課題 プロジェクト作成時のシングルモジュールのままなので、 • .pbxprojのコンフリクトが起きる • Previewの更新に1分〜かかる • 依存関係を把握しにくい 19

20.

マルチモジュール化|決めたこと • SPMのパッケージを1つ作ってモジュールを定義する • 新機能はパッケージに置く • 既存のシングルモジュールはパッケージに依存するが、その逆は禁 する • 新機能が既存のModelやRepositoryを使う場合は、既存のものをDeprecated にしてパッケージに複製する 止 20

21.

マルチモジュール化|結果 1モジュールごとにSchemeを作ることで、Previewの反映を2秒程度でできる ようになった 機能ごとに加えて、アーキテクチャのレイヤーごとにモジュールを分けることで 依存関係を把握しやすくなった 21

22.

アーキテクチャの体系化 22

23.

パッケージに追加する新機能を、ひとまずSwiftUI + MVVMで実装する 針にした ところが、メンバーごとにMVVMの具体的な 針が異なっていたため、 レビューでのコミュニケーションコストが すぎた 方 23 高 方 アーキテクチャの体系化|課題

24.

アーキテクチャの体系化|課題 というのも、MVVMは思想でとどまっており、ライブラリとしてコードに縛りを 設けるわけではない メンバーごとの経験の違いから、細かい部分で思想の違いが出てくる 最初に決めてから進めるべきだったが、Android版で先 リリース済みの新機能 の実装に追われてしまい、メンバーの経験に任せる形になってしまった 行 24

25.

アーキテクチャの体系化|課題 また、既存のコードもMVVMっぽいが、責務の分離が曖昧だった VC VM RepositoryProvider Repository Request Model 25

26.

アーキテクチャの体系化|課題 VC VM RepositoryProvider Repository Request Model 理想の分離 1. VMがレスポンスを受け取り、画 表 の値として加 する 2. VMがRxSwiftで通知する 3. 通知を受け取ったVCが値をViewに反映する 工 用 示 面 26

27.

アーキテクチャの体系化|課題 VC VM RepositoryProvider Repository Request Model の値としてある程度加 する 3. 通知を受け取ったVCがそこそこ複雑なロジックで値をさらに加 する 実際の分離 1. VMがレスポンスを受け取り、画 表 2. VMがRxSwiftで通知する 4. VCが値をViewに反映する 工 工 用 示 面 27

28.

アーキテクチャの体系化|課題 VC VM RepositoryProvider Repository Request Model 状態管理がVMに閉じていない VMだけでは状態のテストをできない 28

29.

アーキテクチャの体系化|課題 VC VM RepositoryProvider Repository Request Model 通信処理をRepository層に実装してDIしようとしている しかし、全てのRepositoryをまとめたRepositoryProviderをVMが参照している • 全てのVMが全てのRepositoryを使えてしまう • テストシナリオに応じたRepositoryのDIが難しい 29

30.

アーキテクチャの体系化|課題 課題をまとめると、 • MVVMに対する思想の細かい違いから、レビューでのコミュニケーション コストが い • 元の責務分離や依存の切り分けが曖昧でテストを書きにくい 特にコミュニケーションコストが きな課題 大 高 30

31.

アーキテクチャの体系化|TCA The Composable Architectureを導 することにした アーキテクチャであり、ライブラリでもある AndroidだとFluxが似ている Store Action Effect State 31 入 View Reducer

32.

アーキテクチャの体系化|TCA 導 した きな理由 • ライブラリとしてコードに縛りを設けられる • 社内でPastela、pixiv、pixiv Sketchに導 済み 懸念点 • 学習コストが い • 将来的に負債になってしまうかも 入 高 大 入 32

33.

アーキテクチャの体系化|TCAの導 理由 ライブラリとしてコードに縛りを設けられる どこに何を書くのかが決まっている • State: 画 表 で使う状態 • Action: イベントの種類 • Reducer: 状態を更新する処理 • Effect: awaitなどの副作 入 用 示 面 33

34.

アーキテクチャの体系化|TCAの導 理由 ライブラリとしてコードに縛りを設けられる 誰が書いてもだいたい同じコードになる →実装する時はどこに何を書くかがわかりやすい →レビューする時はどこを読むかがわかりやすい 入 34

35.

学習コストが 確かに い... いが、既にPastela、pixiv、pixiv Sketchで導 していた 分がそれらのチームでも開発していたので、Palcyの1画 せた に導 また、オープンソースなので内部実装やサンプル、Discussionsを して実装例を られる → カバーできると判断した 見 入 面 入 高 35 高 示 自 アーキテクチャの体系化|TCAの懸念点

36.

アーキテクチャの体系化|TCAの懸念点 将来的に負債になってしまうかも... そうなる頃にはiOS 16サポートを終了してObservationを使えるはず そもそもコードは書いた瞬間から負債であり、将来簡単に移 TCAで責務の分離を厳格に うことが、移 → 将来的に他のアーキテクチャへ移 できることが重要 の容易さにつながる することも可能だと判断した 行 行 行 行 36

37.

アーキテクチャの体系化|TCA導 後 新規モジュール View Reducer Client APIClient Request Model 既存のシングルモジュール VM UseCase Repository 37 入 VC

38.

アーキテクチャの体系化|TCA導 後 新規モジュール View Reducer Client APIClient Request Model 既存のシングルモジュール VC VM UseCase Repository Client / Repository 通信処理などをDIできるように剥がす Clientは、既存のシングルモジュールへの画 ときにも定義する 遷移で依存の向きを逆転させる 入 面 38

39.

アーキテクチャの体系化|TCA導 後 新規モジュール View Reducer Client APIClient Request Model 既存のシングルモジュール VC VM UseCase Repository APIClient → Request 通信ライブラリへの依存を剥がす 入 39

40.

アーキテクチャの体系化|TCA導 後 新規モジュール View Reducer Client APIClient Request Model 既存のシングルモジュール VC VM UseCase Repository UseCase 複数のRepositoryを使うロジックを実装する 既存のViewModelはテストが難しい構造なので、追加するロジックをテスト できるように独 させる 入 立 40

41.

アーキテクチャの体系化|TCA導 後 新規モジュール View Reducer Client APIClient Request Model 既存のシングルモジュール VC VM UseCase Repository ReducerとUseCaseは必ずテストを書く 入 41

42.

導 前: MVVMに対する思想の細かい違いから、レビューでのコミュニケーション コストが い →どこに何を書くかがライブラリとして決まっており、思想の細かい違いが まれにくい →レビューコストを下げられた →学習コスト増加よりレビューコスト低下の が きい 大 方 高 42 入 生 アーキテクチャの体系化|結果

43.

導 前: 元の責務分離や依存の切り分けが曖昧でテストを書きにくい →レイヤーを再定義して、どのレイヤーでテストを書くか決めた →TCAと付属するライブラリで、テストの書き さくできた を統 しつつDIの単位を 一 方 43 入 小 アーキテクチャの体系化|結果

44.

まとめ 44

45.

まとめ|1/2 この1年で、現在では9年 となるiOSアプリにあたりまえを導 した 1. フォーマッタの導 2. マルチモジュール化 3. アーキテクチャの体系化 4. CI/CD(Continuous Delivery)の整備 5. ADR(Any Decision Record)の整備 6. 新しいデザインへの対応 入 目 入 45

46.

まとめ|2/2 特に考えていたこと • 選択肢に挙がる時点でどれも きなメリットを持っており、簡単に剥がせ ないならデメリットに注 する • コードは書いた瞬間から負債であり、将来簡単に移 できることが重要 • 体系化するだけでなく、ルールを守りやすい仕組みまで作る 行 大 目 46