---
title: 8年目iOSアプリにあたりまえを導入する
tags: 
author: [Ockey](https://docswell.com/user/Ockey)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/Y76W9P497V.jpg?width=480
description: 8年目iOSアプリにあたりまえを導入する by Ockey
published: October 07, 26
canonical: https://docswell.com/s/Ockey/59NDPV-StandardPracticiesForiOSAppIn8Year
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/Y76W9P497V.jpg)

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


# Page. 2

![Page Image](https://bcdn.docswell.com/page/G75MNKQD74.jpg)

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


# Page. 3

![Page Image](https://bcdn.docswell.com/page/9J295WWMER.jpg)

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


# Page. 4

![Page Image](https://bcdn.docswell.com/page/DEY4KLLPJM.jpg)

課題
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/VJNYR44M78.jpg)

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


# Page. 6

![Page Image](https://bcdn.docswell.com/page/YE9PMQQWJ3.jpg)

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


# Page. 7

![Page Image](https://bcdn.docswell.com/page/GE8DLGGRED.jpg)

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


# Page. 8

![Page Image](https://bcdn.docswell.com/page/LELMLGG27R.jpg)

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


# Page. 9

![Page Image](https://bcdn.docswell.com/page/4JMYMQQ9JW.jpg)

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


# Page. 10

![Page Image](https://bcdn.docswell.com/page/PJR9V88979.jpg)

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


# Page. 11

![Page Image](https://bcdn.docswell.com/page/PEXQZ883JX.jpg)

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


# Page. 12

![Page Image](https://bcdn.docswell.com/page/3EK98KKNED.jpg)

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


# Page. 13

![Page Image](https://bcdn.docswell.com/page/L73W2ZZZ75.jpg)

フォーマッタの導
入
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/87DKZRR4JG.jpg)

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


# Page. 15

![Page Image](https://bcdn.docswell.com/page/VJPKDWWVE8.jpg)

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


# Page. 16

![Page Image](https://bcdn.docswell.com/page/2EVV188REQ.jpg)

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


# Page. 17

![Page Image](https://bcdn.docswell.com/page/57GL2556EL.jpg)

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


# Page. 18

![Page Image](https://bcdn.docswell.com/page/4EQYPZZ2JP.jpg)

マルチモジュール化
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/KJ4WY33P71.jpg)

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


# Page. 20

![Page Image](https://bcdn.docswell.com/page/LE1Y611X7G.jpg)

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


# Page. 21

![Page Image](https://bcdn.docswell.com/page/GEWGW88KJ2.jpg)

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


# Page. 22

![Page Image](https://bcdn.docswell.com/page/47ZL588NJ3.jpg)

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


# Page. 23

![Page Image](https://bcdn.docswell.com/page/YJ6W9PP9JV.jpg)

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


# Page. 24

![Page Image](https://bcdn.docswell.com/page/GJ5MNKKDJ4.jpg)

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


# Page. 25

![Page Image](https://bcdn.docswell.com/page/9E295W6M7R.jpg)

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


# Page. 26

![Page Image](https://bcdn.docswell.com/page/D7Y4KL9PEM.jpg)

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


# Page. 27

![Page Image](https://bcdn.docswell.com/page/VENYR4LMJ8.jpg)

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


# Page. 28

![Page Image](https://bcdn.docswell.com/page/Y79PMQ4WE3.jpg)

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


# Page. 29

![Page Image](https://bcdn.docswell.com/page/G78DLGQR7D.jpg)

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


# Page. 30

![Page Image](https://bcdn.docswell.com/page/L7LMLGX2JR.jpg)

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


# Page. 31

![Page Image](https://bcdn.docswell.com/page/4EMYMQL9EW.jpg)

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


# Page. 32

![Page Image](https://bcdn.docswell.com/page/PER9V8K9J9.jpg)

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


# Page. 33

![Page Image](https://bcdn.docswell.com/page/P7XQZ8L3EX.jpg)

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


# Page. 34

![Page Image](https://bcdn.docswell.com/page/37K98KLN7D.jpg)

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


# Page. 35

![Page Image](https://bcdn.docswell.com/page/LJ3W2Z3ZJ5.jpg)

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


# Page. 36

![Page Image](https://bcdn.docswell.com/page/8JDKZR44EG.jpg)

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


# Page. 37

![Page Image](https://bcdn.docswell.com/page/VEPKDWMV78.jpg)

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


# Page. 38

![Page Image](https://bcdn.docswell.com/page/27VV189R7Q.jpg)

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


# Page. 39

![Page Image](https://bcdn.docswell.com/page/5JGL25Z67L.jpg)

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


# Page. 40

![Page Image](https://bcdn.docswell.com/page/47QYPZL2EP.jpg)

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


# Page. 41

![Page Image](https://bcdn.docswell.com/page/KE4WY3DPJ1.jpg)

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


# Page. 42

![Page Image](https://bcdn.docswell.com/page/L71Y61ZXJG.jpg)

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


# Page. 43

![Page Image](https://bcdn.docswell.com/page/G7WGW89KE2.jpg)

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


# Page. 44

![Page Image](https://bcdn.docswell.com/page/4JZL589NE3.jpg)

まとめ
44


# Page. 45

![Page Image](https://bcdn.docswell.com/page/YE6W9PK9EV.jpg)

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


# Page. 46

![Page Image](https://bcdn.docswell.com/page/GE5MNKPDE4.jpg)

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


