Slide 1

Slide 1 text

「家族アルバム みてね」を支える ビルド環境の改善 iOSDC Japan 2022 佐藤 光

Slide 2

Slide 2 text

mixi, Inc. 自己紹介 ● 佐藤 光 ( @hicka04 ) ● 株式会社ミクシィ みてね事業部 プロダクト開発グループ ○ 2021/11 中途入社 ● 私自身「家族アルバム みてね(以下みてね) 」ユーザー ● 好きなもの ○ ラーメン ○ ポケモン

Slide 3

Slide 3 text

mixi, Inc. 家族アルバム みてね ● 家族で子供の写真を簡単に共有できるサービス ● 「世界中の家族の”こころのインフラ”を作る」 をミッションに掲げ、現在7言語対応 ● 利用者数が1,500万人(※) を突破(2022年8月現在) ママやパパの「半数」が使うアプリに ※iOS・Android™ アプリ登録者数、ブラウザ版登録者数の合計

Slide 4

Slide 4 text

mixi, Inc. アジェンダ ● Before: 2021年時点でのみてねiOSのビルド環境 ● 改善のフロー ● 実施してきた改善 ● After: 2022年現在のみてねiOSのビルド環境 ● 今後の展望 ● まとめ

Slide 5

Slide 5 text

Before: 2021年時点でのみてねiOSのビルド環境

Slide 6

Slide 6 text

mixi, Inc. Before: 2021年時点でのみてねiOSのビルド環境 ● Xcode 12.0 ● iOS 11.0+ ● マルチモジュール ○ Embedded Framework ● パッケージマネージャ ○ CocoaPods, Carthage ● Bitrise ● MacBook (Intel)

Slide 7

Slide 7 text

mixi, Inc. 少し脱線: 2021年時点でのみてねiOSの開発環境 ● アプリ開発チーム 約10人強 ● iOS/Android/Serverのすべてのタスクを実施 ○ 各々の得意分野はありますが、得意分野にとらわれず様々なタスクにチャレンジする環境 ○ AndroidやServerを得意とするメンバーもiOS開発に携わる

Slide 8

Slide 8 text

改善のフロー

Slide 9

Slide 9 text

mixi, Inc. 改善のフロー ● 改善したいことリストをスクラムボードで管理 ○ 各自課題だと思ったことをストーリーとして追加しておく ● iOS定例 ○ iOSを得意としているメンバーが週に1回集まる ○ 優先順位をつけて、上から順番に実施 ● 20%ルール ○ 各自の時間のうち20%を好きな改善活動に当てることができる ■ 毎週X曜日、毎日1.5時間など、20%ルールの時間の確保の仕方は人それぞれ ○ ビルド環境の改善、コードベースの改善、運用フローの改善、など自由に選択

Slide 10

Slide 10 text

mixi, Inc. 少し脱線: iOS定例 ● 定期的に集まって課題を確認し、より良い解決策がないか議論 ● 設計やコーディングルールなど、全体に影響する内容について方針を決める ○ 中長期に渡る大規模な変更時に移行計画を考える

Slide 11

Slide 11 text

実施してきた改善

Slide 12

Slide 12 text

mixi, Inc. 実施してきた改善 ● Xcode, サポートOS バージョンアップ ● Apple Silicon対応 ● Swift Package Managerの活用 ● ビルド時間の改善 ● その他

Slide 13

Slide 13 text

実施してきた改善 Xcode, サポートOSのバージョンアップ

Slide 14

Slide 14 text

mixi, Inc. 実施してきた改善 - Xcode, サポートOSのバージョンアップ ● iOS 直近3メジャーバージョンをサポートするポリシー ○ iOS16のリリースに合わせて対応中 ● スケジュール ○ 8-9月: iOS β版で動作確認 ○ 9月: iOSメジャーアップデート ○ 10月: 一番古いサポートOSの利用状況の調査 & 報告 ○ 11月: Xcode, サポートOSのメジャーバージョンアップ ● 例外: Xcodeのマイナーバージョンは適宜対応 ○ Xcode 13.2: Swift Concurrency iOS13以上サポート バックポート

Slide 15

Slide 15 text

mixi, Inc. 実施してきた改善 - Xcode, サポートOSのバージョンアップ ● Xcode 13.4.1 ● iOS 13.0+ ● 直近の導入実績 ○ Diffable Data Source ○ Swift Concurrency → https://speakerdeck.com/hicka04/swift-concurrencywodao-ru-suruniatatutejue-metakoto

Slide 16

Slide 16 text

実施してきた改善 Apple Silicon対応

Slide 17

Slide 17 text

mixi, Inc. 実施してきた改善 - Apple Silicon対応 ● WWDC2020にて発表 ● iOS開発: シミュレーターのビルドがエラーに ○ x86_64 → arm64 ● 背景 ○ 今後発売されるMacはApple Siliconの端末が中心になっていくと予想 ○ Apple Silicon端末の利用によるビルド速度向上に期待 ● Rosettaは使わない ○ 環境構築の手間を減らす ○ Apple Siliconが持つ本来のパフォーマンスで開発したい

Slide 18

Slide 18 text

mixi, Inc. 実施してきた改善 - Apple Silicon対応 ● やることリスト ○ ① Carthageで生成するバイナリ .framework → .xcframework ○ ② 他社からいただいているバイナリ .framework → .xcframework ○ ③ ライブラリのアップデート (Apple Siliconに対応したバージョンへ)

Slide 19

Slide 19 text

mixi, Inc. 実施してきた改善 - Apple Silicon対応 ● やることリスト ○ ① Carthageで生成するバイナリ .framework → .xcframework ○ ② 他社からいただいているバイナリ .framework → .xcframework ○ ③ ライブラリのアップデート (Apple Siliconに対応したバージョンへ) ● すぐにすべて対応できなかったため、 iOSシミュレーターのアーキテクチャから arm64 を除外 → Apple Silicon端末でシミュレータービルドができる状態になった ○ EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64

Slide 20

Slide 20 text

mixi, Inc. 実施してきた改善 - Apple Silicon対応 ● やることリスト ○ ① Carthageで生成するバイナリ .framework → .xcframework ○ ② 他社からいただいているバイナリ .framework → .xcframework ○ ③ ライブラリのアップデート (Apple Siliconに対応したバージョンへ) ● すぐにすべて対応できなかったため、 iOSシミュレーターのアーキテクチャから arm64 を除外 → Apple Silicon端末でシミュレータービルドができる状態になった ○ EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64 ● Swift Package Managerを使うとビルドエラーになってしまう

Slide 21

Slide 21 text

mixi, Inc. 実施してきた改善 - Apple Silicon対応 ● ① Carthageで生成するバイナリ ● ② 他社からいただいているバイナリ ● ③ 依存ライブラリのアップデート

Slide 22

Slide 22 text

mixi, Inc. 実施してきた改善 - Apple Silicon対応 ● ① Carthageで生成するバイナリ ○ バイナリ生成時のコマンド引数に --use-xcframework オプションをつける ● ② 他社からいただいているバイナリ ● ③ 依存ライブラリのアップデート

Slide 23

Slide 23 text

mixi, Inc. 実施してきた改善 - Apple Silicon対応 ● ① Carthageで生成するバイナリ ○ バイナリ生成時のコマンド引数に --use-xcframework オプションをつける ● ② 他社からいただいているバイナリ ○ ライブラリ作成元の各社にApple Siliconに対応した .xcframework を作成依頼 → すべて対応いただいた ● ③ 依存ライブラリのアップデート

Slide 24

Slide 24 text

mixi, Inc. 実施してきた改善 - Apple Silicon対応 ● ① Carthageで生成するバイナリ ○ バイナリ生成時のコマンド引数に --use-xcframework オプションをつける ● ② 他社からいただいているバイナリ ○ ライブラリ作成元の各社にApple Siliconに対応した .xcframework を作成依頼 → すべて対応いただいた ● ③ 依存ライブラリのアップデート ○ 中でもRealm v3系 → v10系 への大幅なメジャーバージョンアップが鬼門 ■ 過去にバージョンアップを試して、クラッシュやフリーズ等の問題が発生していた ■ 問題を再現させて着実に修正し、無事にアップデートできた

Slide 25

Slide 25 text

mixi, Inc. 実施してきた改善 - Apple Silicon対応 ● iOSシミュレーターのアーキテクチャから arm64 を除外する設定を削除 → Rosettaを使わずにApple Silicon端末で開発できる環境を実現できた! → Swift Package Managerを使えるようになった!

Slide 26

Slide 26 text

mixi, Inc. 実施してきた改善 - Apple Silicon対応 ● iOSシミュレーターのアーキテクチャから arm64 を除外する設定を削除 → Rosettaを使わずにApple Silicon端末で開発できる環境を実現できた! → Swift Package Managerを使えるようになった! ● ビルド時間はIntelと比較して約1.5倍以上高速 ※1 ○ 適宜Apple Silicon端末へのリプレイスを行って生産性向上 チップ フルビルド 差分ビルド Intel ※2 300s 33.8s Apple Silicon ※3 200s 19.3s ※1 ビルド3回実行時の平均値で比較 ※2 MacBook Pro (16-inch, 2019) 32GBメモリ ※3 MacBook Air (M1, 2020) 16GBメモリ

Slide 27

Slide 27 text

実施してきた改善 Swift Package Managerの活用

Slide 28

Slide 28 text

mixi, Inc. 実施してきた改善 - Swift Package Managerの活用 ● WWDC2019にて発表 ● Xcode11以降、GUI上からSwift Package Manager (以下SwiftPM) を扱えるようになった ● みてねではCocoaPodsとCarthageを中心にライブラリを管理 ○ CocoaPods: Rubyのセットアップが必要 ○ Carthage: 過去、Xcodeのアップデートでビルドできない問題が発生 ● SwiftPM: 1st Partyのパッケージマネージャ ○ 特別なセットアップが不要 ○ Xcodeのアップデートに自動で追従してくれる

Slide 29

Slide 29 text

mixi, Inc. 実施してきた改善 - Swift Package Managerの活用 ● 依存ライブラリの一覧を作成し、それぞれ対応方法を決定 ○ 不要なライブラリは削除 ■ 現在はAppleが発表したフレームワークやSwiftの言語機能だけで実現できるようになったものなど ○ 基本的にはSwiftPMに移行 ○ ライブラリ側がSwiftPMに対応していない場合は、Carthage > CocoaPodsの優先順位 ■ Carthageによる事前ビルドでビルド時間を短縮

Slide 30

Slide 30 text

mixi, Inc. 実施してきた改善 - Swift Package Managerの活用 ● 依存ライブラリの一覧を作成し、それぞれ対応方法を決定 ○ 不要なライブラリは削除 ■ 現在はAppleが発表したフレームワークやSwiftの言語機能だけで実現できるようになったものなど ○ 基本的にはSwiftPMに移行 ○ ライブラリ側がSwiftPMに対応していない場合は、Carthage > CocoaPodsの優先順位 ■ Carthageによる事前ビルドでビルド時間を短縮 ● 1個の不要ライブラリを削除完了 4個がSwiftPM利用 (14%)

Slide 31

Slide 31 text

実施してきた改善 ビルド時間の改善

Slide 32

Slide 32 text

mixi, Inc. 実施してきた改善 - ビルド時間の改善 ● マルチモジュール化 ● ビルドフェーズの整理

Slide 33

Slide 33 text

mixi, Inc. 実施してきた改善 - ビルド時間の改善 - マルチモジュール化 ● 期待している効果 ○ 変更していないモジュールのビルドをスキップ ○ 並列ビルドが効きやすくなる ● レイヤーごとにモジュール分割 ○ クリーンアーキテクチャの円の境界 ≒ モジュールの境界 ○ Embedded Frameworkでモジュールを作成

Slide 34

Slide 34 text

mixi, Inc. 実施してきた改善 - ビルド時間の改善 - マルチモジュール化 ● ビルド時間高速化の恩恵を十分に受けられていない ○ モジュールをまたいでファイルを変更することが多い (特にUI層とPresentation層) ● プロジェクトファイルのコンフリクトが発生しやすい ○ XcodeGen等のコンフリクトを回避する手段が未導入

Slide 35

Slide 35 text

mixi, Inc. 実施してきた改善 - ビルド時間の改善 - マルチモジュール化 ● ビルド時間高速化の恩恵を十分に受けられていない ○ モジュールをまたいでファイルを変更することが多い (特にUI層とPresentation層) → レイヤー × Feature のモジュール分割 ● プロジェクトファイルのコンフリクトが発生しやすい ○ XcodeGen等のコンフリクトを回避する手段が未導入

Slide 36

Slide 36 text

mixi, Inc. 実施してきた改善 - ビルド時間の改善 - マルチモジュール化 ● ビルド時間高速化の恩恵を十分に受けられていない ○ モジュールをまたいでファイルを変更することが多い (特にUI層とPresentation層) → レイヤー × Feature のモジュール分割 ● プロジェクトファイルのコンフリクトが発生しやすい ○ XcodeGen等のコンフリクトを回避する手段が未導入 → SwiftPMのローカルパッケージに変更 参考: iOSDC2021「Swift Package中心のプロジェクト構成とその実践」 https://fortee.jp/iosdc-japan-2021/proposal/1338c9cc-363a-44a6-bbac-452b67b472fb

Slide 37

Slide 37 text

mixi, Inc. 実施してきた改善 - ビルド時間の改善 - マルチモジュール化 ● SwiftPM ローカルパッケージ ○ Framework → Package ● UI + Presentation = Feature 機能ごとにターゲットが分かれる ● 移行計画 ○ 依存関係の末端から切り出し

Slide 38

Slide 38 text

mixi, Inc. 実施してきた改善 - ビルド時間の改善 - マルチモジュール化 ● SwiftPM ローカルパッケージ ○ Framework → Package ● UI + Presentation = Feature 機能ごとにターゲットが分かれる ● 移行計画 ○ 依存関係の末端から切り出し ● 現在移行中 ○ ビルド速度が改善しているかは いずれどこかで共有したい

Slide 39

Slide 39 text

mixi, Inc. 実施してきた改善 - ビルド時間の改善 - ビルドフェーズの整理 ● コードの自動生成系 ○ SwiftGen (Image, Color, L10n) ○ Sourcery (Mock, Stub, DI) ● Lint, Format系 ○ SwiftLint ○ SwiftFormat

Slide 40

Slide 40 text

mixi, Inc. 実施してきた改善 - ビルド時間の改善 - ビルドフェーズの整理 ● コードの自動生成系 ○ SwiftGen (Image, Color, L10n) ○ Sourcery (Mock, Stub, DI) → 開発時に自動生成されたコードを即時利用してコーディングしたい ● Lint, Format系 ○ SwiftLint ○ SwiftFormat

Slide 41

Slide 41 text

mixi, Inc. 実施してきた改善 - ビルド時間の改善 - ビルドフェーズの整理 ● コードの自動生成系 ○ SwiftGen (Image, Color, L10n) ○ Sourcery (Mock, Stub, DI) → 開発時に自動生成されたコードを即時利用してコーディングしたい ● Lint, Format系 ○ SwiftLint ○ SwiftFormat → ビルドのたびに毎回実行するほど即効性が求められていない

Slide 42

Slide 42 text

mixi, Inc. 実施してきた改善 - ビルド時間の改善 - ビルドフェーズの整理 ● SwiftLint ○ CIで実行され、PR上で警告を確認できる → ビルドフェーズから削除: 約3.0s ● SwiftFormat ○ 実行時エラーを生み出すような危険な変更が行われない → ビルドフェーズから削除: 約2.4s ○ Dailyでmainブランチに対してフォーマットを実行しPRを作る ※計測条件 ● MacBook Air (M1, 2020) ● 差分ビルド3回実行時の平均値

Slide 43

Slide 43 text

mixi, Inc. 実施してきた改善 - ビルド時間の改善 - ビルドフェーズの整理 ● SwiftLint ○ CIで実行され、PR上で警告を確認できる → ビルドフェーズから削除: 約3.0s ● SwiftFormat ○ 実行時エラーを生み出すような危険な変更が行われない → ビルドフェーズから削除: 約2.4s ○ Dailyでmainブランチに対してフォーマットを実行しPRを作る ● 差分ビルド約12.4sの改善 (約1.8倍高速化) ○ SwiftFormatによる余分なファイル差分が生まれなくなり、 無駄に実行されていたビルドステップ減少 ※計測条件 ● MacBook Air (M1, 2020) ● 差分ビルド3回実行時の平均値

Slide 44

Slide 44 text

実施してきた改善 その他

Slide 45

Slide 45 text

mixi, Inc. 実施してきた改善 - その他 ● QA用ビルド作成の簡略化 ○ 各作業ブランチでQAを実施 ■ ブランチ名をコピペしてビルド作成するのが地味に面倒 ○ → PRに QA ラベルを付けておくと、最新コミットでQA用ビルド作成 ■ ラベルの判別(GitHub Actions) → ビルド作成(Bitrise)

Slide 46

Slide 46 text

mixi, Inc. 実施してきた改善 - その他 ● QA用ビルド作成の簡略化 ○ 各作業ブランチでQAを実施 ■ ブランチ名をコピペしてビルド作成するのが地味に面倒 ○ → PRに QA ラベルを付けておくと、最新コミットでQA用ビルド作成 ■ ラベルの判別(GitHub Actions) → ビルド作成(Bitrise) ● Bitriseのワークフローの整理 ○ 使われていないまま放置されていたワークフロー削除 ○ ワークフローの共通化 ■ Clone, CachePull, Bootstrap, CachePush, …etc ○ Clone時のdepthを1に ■ 4min → 2min

Slide 47

Slide 47 text

After: 2022年現在のみてねiOSのビルド環境

Slide 48

Slide 48 text

mixi, Inc. After: 2022年現在のみてねiOSのビルド環境 ※絶賛移行中 ● Xcode 13.4.1 ● iOS 13.0+ ● マルチモジュール ○ SwiftPM ローカルパッケージ ※ ● パッケージマネージャ ○ SwiftPM, CocoaPods, Carthage ● Bitrise, GitHub Actions ● MacBook (Apple Silicon, Intel)

Slide 49

Slide 49 text

今後の展望

Slide 50

Slide 50 text

mixi, Inc. 今後の展望 ● 定期的なXcodeのバージョンアップ ● サポートOSのバージョンアップ ○ 新しいAPIの導入 ● SwiftPMへの移行 ● マルチモジュール化の推進 ● コードベースの改善 ○ Swift Concurrencyへの移行 ○ デザインシステム推進

Slide 51

Slide 51 text

まとめ

Slide 52

Slide 52 text

mixi, Inc. まとめ ● iOSのビルド環境を取り巻く変化は激しい ○ XcodeやSwift Package Managerのアップデート ○ 新しいMacの登場 ○ …etc ● 現状のプロジェクトが抱える課題の解決手段が増えるのはいいこと ● 追従していくためには、日々の改善が重要 ○ 課題を管理して着実に改善を進めていく

Slide 53

Slide 53 text

最後に

Slide 54

Slide 54 text

mixi, Inc. アプリエンジニアを積極採用してます! ● 発表内容に興味を持ってくださった方 ● ユーザーがたくさんいるサービスに携わりたい方 ● iOS / Android / Server など さまざまな技術分野にチャレンジしたい方 ● 育児関連のサービスに携わりたい方 ● …etc https://team.mitene.us/jobs

Slide 55

Slide 55 text

mixi, Inc.