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

7年開発/運用が続くkencom iOSアプリの全面的リファクタリング【DeNA TechCon 2023】

7年開発/運用が続くkencom iOSアプリの全面的リファクタリング【DeNA TechCon 2023】

youtube:https://youtu.be/ExbncjhxfMM

概要:
kencomは7年以上開発・運用が続いている、ICTを活用したヘルスケアエンターテインメントアプリです。2022年の春から夏にかけて大きくリファクタリングしました。
2022年春の時点では、合計24人のコントリビュータがいるkencomのiOSアプリのコードは秘伝のタレ状態になっていて、不要なライブラリも多数残ったままになっていました。
そこで私達はRxSwiftやRxCocoaをCombineに置き換えたりしながら不要なライブラリのほとんどを断捨離しました。
このセッションでは実際に行った取り組みの詳細について紹介します。

登壇内でのリンク集:
p3, https://kencom.jp

◆ チャンネル登録はこちら↓
https://youtube.com/c/denatech?sub_confirmation=1

◆ Twitter
https://twitter.com/DeNAxTech

◆ DeNA Engineering
https://engineering.dena.com/

◆ DeNA Engineer Blog
https://engineering.dena.com/blog/

◆ DeNA TechCon 2023 公式サイト
https://techcon2023.dena.dev/

DeNA_Tech

March 02, 2023
Tweet

More Decks by DeNA_Tech

Other Decks in Technology

Transcript

  1. 7年開発・運用が続いている
    kencomのiOSアプリの全面的リ
    ファクタリング
    野瀬田 裕樹

    View Slide

  2. 野瀬田 裕樹
    所属 ヘルスケア事業本部
    製品開発部モバイルソリューションG
    担当 iOS/Androidエンジニア
    出身地 京都府
    家族構成 妻と4歳の長男の3人家族
    2
    @ynoseda

    View Slide

  3. kencomとは
    ● https://kencom.jp/
    ● 2015年10月にv1.0.0をリリース
    ● 楽しみながら健康になれることを促す
    ● 健康保険組合・自治体などの団体に対
    して販売を行っている
    ○ 団体に所属している人だけが使える
    ● 健康診断の結果の閲覧、健康状態に応
    じた記事のレコメンド、歩数データの
    管理などができる
    3

    View Slide

  4. ● 1st commit:2015年6月5日
    kencom iOSアプリの開発の履歴
    4

    View Slide

  5. ● 1st commit:2015年6月5日
    ● 1st release:2015年10月8日
    =開発期間4ヶ月
    kencom iOSアプリの開発の履歴
    5

    View Slide

  6. ● 1st commit:2015年6月5日
    ● 1st release:2015年10月8日
    ● 基本的には100% swift
    kencom iOSアプリの開発の履歴
    6

    View Slide

  7. ● 1st commit:2015年6月5日
    ● 1st release:2015年10月8日
    ● 基本的には100% swift
    ● 短期間での開発のためか初期から負債が蓄積された状態
    ○ Realmを使っているが不安定で壊れたりしていた(その後に削除)
    ○ FatViewController、FatStoryboard
    ○ ViewController内でviewの位置調整などを多数やっている
    kencom iOSアプリの開発の履歴
    7

    View Slide

  8. ● 現時点で24 Contributors
    ● gitのログから大規模なアプリの機能改修は今まであまりなく、
    リファクタを推進するきっかけに乏しかった様子が伺える
    kencom iOSアプリの開発の履歴
    8

    View Slide

  9. ● 現時点で24 Contributors
    ● 大規模なアプリの機能改修は今まであまりなかった
    ● その結果、秘伝のタレコードが多数発生
    ● 以下のような課題が発生
    ○ 提供する機能要件に対して不必要に多いコード量
    ○ 現在では不要になった多数のOSSのライブラリ
    ○ 結果としてビルド時間が長くなってきた
    kencom iOSアプリの開発の履歴
    9

    View Slide

  10. ● 色々な負債が存在していたため、全てをリファクタは困難
    リファクタリングの方針
    10
    秘伝のタレ
    重いビルド 古い設計
    不要な実装
    古い書き方

    View Slide

  11. ● 色々な負債が存在していたため、全てをリファクタは困難
    ● そこでまずは今後の開発を楽にするためのリファクタを実施
    ● リファクタリングの方針
    ○ 通信部分の刷新 → 今後の機能開発で簡潔に書けるようになる
    ○ プロジェクト全体のスリム化 → 断捨離でビルド時間短縮を期待
    リファクタリングの方針
    11

    View Slide

  12. ● 通信ライブラリの選定
    ● インターフェース設計
    ● 通信呼び出し部分の差し替え作業
    通信部分の刷新
    12

    View Slide

  13. ● 旧実装ではライブラリとしてMoyaを採用
    ● MoyaとはAlamofireをラップしたライブラリ
    通信部分の刷新:通信ライブラリの選定
    13

    View Slide

  14. ● 旧実装ではライブラリとしてMoyaを採用
    ● MoyaとはAlamofireをラップした通信用のライブラリ
    ● しかし、旧実装ではMoyaのメリットが活かせていない状態
    ○ 通信部分の単体テストは行ってない
    ○ Moyaを更にラップした通信クラスがある
    通信部分の刷新:通信ライブラリの選定
    14

    View Slide

  15. ● 考えられる方針
    ○ ライブラリは今のまま:Moyaのメリットを最大限に生かす
    ○ ライブラリを使わない:URLSessionを直接使用する
    ○ 使うライブラリを変更する:Alamofireに切り替える
    通信部分の刷新:通信ライブラリの選定
    15

    View Slide

  16. ● 考えられる方針
    ○ ライブラリは今のまま:Moyaのメリットを最大限に生かす
    ○ ライブラリを使わない:URLSessionを直接使用する
    ○ 使うライブラリを変更する:Alamofireに切り替える
    通信部分の刷新:通信ライブラリの選定
    16

    View Slide

  17. ● 旧実装のインターフェースはRxSwiftのObservable
    ● 具体的には、request関数の返り値がObservable
    通信部分の刷新:通信のインターフェース
    17

    View Slide

  18. ● 昔はRxSwiftを利用したReactiveプログラミングが多かった
    ● Swift 5.5からasync/awaitを使った非同期処理が可能になった
    ● 同期処理のコードにasync/awaitのキーワードを追加するだけで
    非同期処理になるので非常にシンプルに書ける
    補足)Swiftの非同期処理について
    18

    View Slide

  19. 通信部分の刷新:実装イメージ
    19
    ● 通信を行うstaticな関数を準備
    ● 新しい実装ではasyncな関数として通信のI/Fを用意

    View Slide

  20. 通信部分の刷新:実装イメージ
    20
    ● APIのリクエストに必要なものを実装するためのprotocolを準備

    View Slide

  21. ● 作業手順
    ○ 全てのAPIを一覧にしてチェックリストを準備
    ○ API一つにつきAPIRequestに適合したstructを準備
    ○ 一つずつ新しいrequest関数に置き換え
    ○ 全て置き換えが完了したら古いコードを削除
    通信部分の刷新
    21

    View Slide

  22. ● 作業手順
    ○ 全てのAPIを一覧にしてチェックリストを準備
    ○ API一つにつきAPIRequestに適合したstructを準備
    ○ 一つずつ新しいrequest関数に置き換え
    ○ 全て置き換えが完了したら古いコードを削除
    通信部分の刷新
    22

    View Slide

  23. ● 利用しているライブラリの見直しを実施
    ○ 元々使用していたライブラリの数:25個
    ○ 断捨離できるライブラリの数:半分以上
    ● 元々使っていたライブラリの例
    ○ Rx系(RxSwift, RxCocoa)
    ○ ObjectMapper
    ○ CryptoSwift
    プロジェクト全体のスリム化
    23

    View Slide

  24. ● Rx系の断捨離の方針案
    a. 対応するCombineのコードで置き換え
    b. 個別に最適な実装にリファクタ
    プロジェクト全体のスリム化:Rx系の断捨離
    24

    View Slide

  25. ● Rx系の断捨離の方針案
    a. 対応するCombineのコードで置き換え
    b. 個別に最適な実装にリファクタ
    c. 一部はリファクタするが、大半は機械的にCombineに置き換え
    プロジェクト全体のスリム化:Rx系の断捨離
    25

    View Slide

  26. ● Rx系の断捨離の対応内容
    ○ ほぼ機械的にCombineのコードに置換できたため、ひたすら置換
    ○ 通信部分やRepositoryへのアクセスはasync/awaitで書き換え
    ○ RxCocoaなど機械的な置換ができない箇所だけ後から手動書き換え
    ○ 基本的に地道な作業なので気合いで修正を完了
    プロジェクト全体のスリム化:Rx系の断捨離
    26

    View Slide

  27. ● ObjectMapperについて
    ○ Jsonと任意のモデルオブジェクトとを相互に変換できる
    ○ 今ではCodableがある
    ○ 通信部分の刷新に合わせて全てCodableに置き換え
    ○ これもほとんど機械的な修正で済むため、気合いで修正
    プロジェクト全体のスリム化:ObjectMapperの断捨離
    27

    View Slide

  28. ● CryptoSwiftについて
    ○ 暗号化/復号化のためのライブラリ
    ○ 標準のCryptoKitに置き換えできる
    ○ 通信のJWTを生成するためだけに使用していたので、すぐに修正完了
    プロジェクト全体のスリム化:CryptoSwiftの断捨離
    28

    View Slide

  29. ● その他の断捨離について(一部)
    ○ SwiftDate → あまり使ってなかったので標準のDateの実装に書き換え
    ○ Appirater → レビューのタイミング調整にだけ使ってたので削除
    ○ XCGLogger → ほぼ使ってなかったので削除
    ○ PKHUD → 自前のローディング画面に置き換え
    ○ Device → 更新されてなかったので削除
    ○ SwiftyDrop → 自前のViewに書き換え
    プロジェクト全体のスリム化
    29

    View Slide

  30. ● 10個以上のライブラリを断捨離
    ● 該当バージョンで3万行以上コードを削減
    リファクタリングの結果
    30

    View Slide

  31. ● ビルド時間は5分以上かかっていたのが1分強に
    リファクタリングの結果
    31

    View Slide

  32. ● QA検知の不具合は計7件
    ● リリース後も大きな問題なく通常運用へ
    ● 要因
    ○ 開発者側での手厚いレビューと開発者検証
    ○ 短期間で集中的にリファクタを進めた
    ○ 機能開発とほぼ並行しないようにした
    ○ 十分に影響範囲をQAに伝えた
    リファクタリングの結果
    32

    View Slide

  33. ● 継続して画面単位での改善も実施中
    ○ 古い設計を新しい設計へ移行
    ○ UIKitからSwiftUIへ移行
    ● 同バージョンでホーム画面の作り直しも実施
    その他のリファクタリング
    33

    View Slide

  34. ● 数字ありバッジがついた丸型アイコンの実装
    ● 単純にoverlayで重ねても、それっぽく見える
    余談)SwiftUIで作ったViewを一部紹介
    34

    View Slide

  35. ● 数字ありバッジがついた丸型アイコンの実装
    ● 単純にoverlayで重ねても、それっぽく見える
    ● しかし、文字サイズを大きくすると位置がずれる
    ○ バッジの位置調整 or アイコンの可変化が必要
    余談)SwiftUIで作ったViewを一部紹介
    35

    View Slide

  36. ● 数字ありバッジがついた丸型アイコンの実装
    ● overlayで重ねたバッジにoffsetを追加して調整
    ● 指定するオフセットはバッジのサイズに応じて可変
    ● 計算式:中学生ぐらいの気分になって考えてみよう
    余談)SwiftUIで作ったViewを一部紹介
    36

    View Slide

  37. ● 数字ありバッジがついた丸型アイコンの実装
    ● overlayで重ねたバッジにoffsetを追加して調整
    ● 指定するオフセットはバッジのサイズに応じて可変
    ● 計算式:バッジの円の半径 - (1-1/√2) × アイコンの円の半径
    余談)SwiftUIで作ったViewを一部紹介
    37

    View Slide

  38. ● リファクタリングは地道な作業なので気合いは必要
    ● 目的と手段を整理し、しっかり下準備すれば成功する
    ● リファクタリングの際には開発者確認とQAをきちんとしよう
    ● ちゃんとテストすれば、案外根幹部分に手を入れても大丈夫
    まとめ
    38

    View Slide

  39. ご清聴ありがとうございました
    良いリファクタリングライフを!
    39

    View Slide