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

Multiplatform Engineering Roadmap for the Future

CyberAgent
December 15, 2021

Multiplatform Engineering Roadmap for the Future

ABEMAはスマートフォンやPC、テレビデバイスなどの様々なプラットフォームで楽しむことができます。

その一方、拡大する対応プラットフォームに対しての開発リソースやプラットフォーム間の機能や仕様差異、品質のばらつきなど様々な課題を抱えています。

また、技術的なトレンドとしてKMM(Kotlin Multiplatform Mobile)やFlutter、React Nativeといったマルチプラットフォーム・クロスプラットフォーム技術が注目を浴びています。

それらの課題と技術的な時流から、ABEMAでもKMMを活用したソースコードの共通化に取り組んでいます。

このセッションでは、クライアントアプリケーション開発におけるマルチプラットフォームエンジニアリングの戦略をはじめ、モバイルアプリケーションにKMMを導入した背景や選定理由、具体的な取り組み、そして今後の展望についてご紹介します。

https://developer.abema.io/2021/sessions/bvjpwJEoGP/?utm_medium=social&utm_source=slideshare

CyberAgent

December 15, 2021
Tweet

More Decks by CyberAgent

Other Decks in Technology

Transcript

  1. AbemaTV, Inc. All Rights Reserved
 鈴木 大貴 Native Team所属。 ABEMAのモバイルアプリ開発及び

    マルチプラットフォームによる開発に従事。 2 波戸 勇二 國師 誠也 自己紹介 Native Team所属。 ABEMAモバイルアプリやテレビアプリ、 マルチプラットフォーム開発に従事。 Native Team所属。 Native Teamマネージャー兼クライアント戦略室 室長。
  2. AbemaTV, Inc. All Rights Reserved
 鈴木 大貴 Native Team所属。 ABEMAのモバイルアプリ開発及び

    マルチプラットフォームによる開発に従事。 3 波戸 勇二 國師 誠也 自己紹介 Native Team所属。 ABEMAモバイルアプリやテレビアプリ、 マルチプラットフォーム開発に従事。 Native Team所属。 Native Teamマネージャー兼クライアント戦略室 室長。
  3. AbemaTV, Inc. All Rights Reserved
 4 1. 対応デバイスの拡大 2. MobileAppが抱えていた課題

    3. リアーキテクチャ 4. KMMのアーキテクチャ 5. バージョン管理 INDEX 6. 既存アプリの移行 7. MobileAppチームへの普及 8. 全体戦略
  4. AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 6 2016年4月11日に開局した当初は、対応デバイスとして iOS・Android (mobile)

    とブラウザ (pc / mobile) からスタート。 2016年4月 開局 iOS mobile Android mobile Web pc / mobile
  5. AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 8 2017年 ~ 2019年にAmazon

    Alexa、Daydream、Amazon Fire Tablet, IPTV, Clova Deskに対応 ※ IPTVはここではLinuxベースのIPTVをさしています 2017年 ~ 2019年 2017/11 Daydream Clova Desk IPTV 2018/03 2019/03 Amazon Alexa Amazon Fire Tablet 2018/11 2017/12 ※ Daydream, Clova Deskはサポート終了
  6. AbemaTV, Inc. All Rights Reserved
 10 ※ Daydream, Clova Deskはサポート終了

    対応デバイスの拡大 2016 iOS mobile Android mobile Web pc / mobile Chrome cast Apple TV Android TV IPTV Daydream Clova Desk Google Nest Hub Game Console 2017 2019 2018 2020 2021 Amazon Alexa Amazon Fire TV Amazon FIre Tablet 2022
  7. AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 11 • 対応デバイスが増えるのに比例して開発リソースが必要 •

    優先度の高いデバイスに開発リソースが偏り、機能差がある • デバイス間で意図しない仕様・実装差異や品質のバラつきがある • レガシーなアプリケーションのメンテナンスコストが高くなる 課題
  8. AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 14 技術スタックは大きく分けて iOS, Android,

    Web, Unity。 技術スタック (プラットフォーム) Android Web Unity iOS ※ Amazon AlexaはAWS Lambdaですがここではスコープ外としています
  9. AbemaTV, Inc. All Rights Reserved
 15 ※ Daydream, Clova Deskはサポート終了

    対応デバイスの拡大 2016 iOS mobile Android mobile Web pc / mobile Chrome cast Apple TV Android TV IPTV Daydream Clova Desk Google Nest Hub Game Console 2017 2019 2018 2020 2021 Amazon Alexa Amazon Fire TV Amazon FIre Tablet 2022 再掲
  10. AbemaTV, Inc. All Rights Reserved
 16 対応デバイスの拡大 Desktop Browser Android

    Web Unity Mobile Browser Mobile App Smart Display/ Speaker TV iOS iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Amazon Fire TV Amazon FIre Tablet Mobile Web ユースケース 技術スタック
  11. AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 17 汎化と特化 Use Cases

    Entities UI Presentation DB 拡大する対応デバイスに対して、汎化できる部分 と特化するべき部分を検討。 サービスの強みとして UI/UX・快適な視聴体験の 追求をしていくために、プレゼンテーション層は各 デバイス・プラットフォームに最適化し特化してい く方針。 デバイス・プラットフォームに依存しないユース ケース、エンティティは汎化できる部分として共通 化を進める。 platform-specific APIs External Interfaces Gateways Presenters Controllers
  12. AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 18 汎化と特化 Use Cases

    Entities UI Presentation DB platform-specific APIs External Interfaces Gateways Presenters Controllers 特化 汎化 • 特化する部分 ◦ プレゼンテーション層 ◦ プラットフォーム固有のエンティティ・ユー スケース • 汎化する部分 ◦ 汎化された外部IF ◦ プラットフォームに依存しないエンティティ ・ユースケース
  13. AbemaTV, Inc. All Rights Reserved
 • UIを含むコードの共通化 (独自UI) - Flutter,

    Unity, Xamarin Forms, Cobalt, ... • UIを含むコードの共通化 (ネイティブUI) - React Native, ... • UIを含むコードの共通化 (WebベースUI) - Cordova, Titanium Mobile, ... • ロジックのみの共通化 - Kotlin Multiplatform, Xamarin Native, ... 対応デバイスの拡大 19 マルチプラットフォーム・クロスプラットフォームツールの検討
  14. AbemaTV, Inc. All Rights Reserved
 • プラットフォームに特化した最適なUI/UXの提供 • プラットフォームAPIへの追従性 •

    開発コミュニティの将来性 • 快適な開発体験 対応デバイスの拡大 20 マルチプラットフォーム・クロスプラットフォームツールの検討
  15. AbemaTV, Inc. All Rights Reserved
 Web Native Cross Device Smart

    Display/ Speaker 22 対応デバイスの拡大 Desktop Browser Mobile Browser Mobile App TV iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Amazon Fire TV Amazon FIre Tablet Mobile Web 開発体制
  16. AbemaTV, Inc. All Rights Reserved
 Web Native Cross Device Smart

    Display/ Speaker 23 対応デバイスの拡大 Desktop Browser Mobile Browser Mobile App TV iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Amazon Fire TV Amazon FIre Tablet Mobile Web 開発体制
  17. AbemaTV, Inc. All Rights Reserved
 鈴木 大貴 Native Team所属。 ABEMAのモバイルアプリ開発及び

    マルチプラットフォームによる開発に従事。 24 波戸 勇二 國師 誠也 自己紹介 Native Team所属。 ABEMAモバイルアプリやテレビアプリ、 マルチプラットフォーム開発に従事。 Native Team所属。 Native Teamマネージャー兼クライアント戦略室 室長。
  18. AbemaTV, Inc. All Rights Reserved
 Mobile Appが抱えていた課題 26 • 設計によってコンポーネント間の疎結合が担保されていない

    • テスタビリティ・メンテナビリティの低さ • AndroidとiOSの仕様・実装差異の拡大 • UI開発の安全性と生産性の低下
  19. AbemaTV, Inc. All Rights Reserved
 Mobile Appが抱えていた課題 27 リアーキテクチャ •

    設計によってコンポーネント間の疎結合が担保されていない • テスタビリティ・メンテナビリティの低さ • AndroidとiOSの仕様・実装差異の拡大 • UI開発の安全性と生産性の低下
  20. AbemaTV, Inc. All Rights Reserved
 Mobile Appが抱えていた課題 28 リアーキテクチャ +

    KMM • 設計によってコンポーネント間の疎結合が担保されていない • テスタビリティ・メンテナビリティの低さ • AndroidとiOSの仕様・実装差異の拡大 • UI開発の安全性と生産性の低下
  21. AbemaTV, Inc. All Rights Reserved
 • 設計によってコンポーネント間の疎結合が担保されていない • テスタビリティ・メンテナビリティの低さ •

    AndroidとiOSの仕様・実装差異の拡大 • UI開発の安全性と生産性の低下 Mobile Appが抱えていた課題 29 リアーキテクチャ + VRT (Visual Regression Test)
  22. AbemaTV, Inc. All Rights Reserved
 • ロジックの置き場所が設計によって担保されない ◦ プラットフォーム間共通のビジネスロジックの分離が困 難

    ◦ テスタビリティ・メンテナビリティの低いコードの増加 ◦ 密結合なコンポーネントによってビルド時間の増加、個 別のビルドが困難 課題 リアーキテクチャ 31 Meta Platforms(旧Facebook)社が提唱したクライアントウェ ブアプリケーションのアーキテクチャ。 ABEMA開局当初(2016年)から採用。 Flux https://facebook.github.io/flux/docs/in-depth-overview
  23. AbemaTV, Inc. All Rights Reserved
 リアーキテクチャ 32 Clean Architectureをベースに、責務によってレイヤーを分割 。

    関心を分離し、各レイヤーの将来的な変更を容易にしている。 https://blog.cleancoder.com/uncle-bob/2012/08/13/ the-clean-architecture.html 新しいアーキテクチャ UI UI Logic UseCase DB API Domain Repository Domain Layer Application Layer UI Layer Data Layer
  24. AbemaTV, Inc. All Rights Reserved
 リアーキテクチャ 33 プラットフォーム(OSやデバイス)やアプリケーションを問わず、サー ビスで共通するドメインモデルとビジネスロジックを実装する。 ・アプリケーション層やデータ層から使用されるデータモデル

    ・ドメインモデルに属する不変なビジネスロジック ・アプリケーションに依存しないビジネスロジック DO DON'T ・アプリケーション固有のビジネスロジック ・UIやDB、APIに依存するロジック UI UI Logic UseCase DB API Domain Repository Domain Layer Application Layer UI Layer Data Layer ドメイン層
  25. AbemaTV, Inc. All Rights Reserved
 リアーキテクチャ 34 アプリケーション固有のロジックを実装する。 ユーザーがアプリケーションを操作して結果を得るまでの一連を 1つ

    のユースケースとする。 ・アプリケーション固有のビジネスロジック ・ユースケースは原則ステートレス ・複数のユースケースで共通するロジックはServiceとして切り出す DO DON'T ・表示と密に関わるもの(文字列や画像リソース) ・ユースケースから他のユースケースの呼び出し UI UI Logic UseCase DB API Domain Repository Domain Layer Application Layer UI Layer Data Layer アプリケーション層
  26. AbemaTV, Inc. All Rights Reserved
 リアーキテクチャ 35 UI UI Logic

    UseCase DB API Domain Repository Domain Layer Application Layer UI Layer Data Layer データソースおよび、それを隠蔽するリポジトリを実装する。 外部のアプリケーションやシステムとの境界。 ・APIとの通信やストレージに対するデータの読み書き ・DBやメモリにキャッシュするデータの管理 DO DON'T ・ドメインロジックやアプリケーションロジック ・リポジトリから他のリポジトリの呼び出し データ層
  27. AbemaTV, Inc. All Rights Reserved
 リアーキテクチャ 36 UI UI Logic

    UseCase DB API Domain Repository Domain Layer Application Layer UI Layer Data Layer UIコンポーネントやOSから通知されるイベントをハンドリングして、ユー スケースを実行する。 ユースケースの結果をUIコンポーネントへ反映する。 ・UIコンポーネントやOSからのイベントとユースケースの紐付け ・UI表示 DO DON'T ・ビジネスロジック UI層
  28. AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャ 39 UI UI Logic

    UseCase DB API Domain Repository Domain Layer Application Layer UI Layer Data Layer 責務によってレイヤーを分割 → 共通のロジックやモデルをまとめることが可能に。 UI層を除いた、ドメイン層・アプリケーション層・データ層をKMMによっ て共通化。 共通化が難しいところは、インタフェースをKMMから提供し、各プラット フォームで実装。 既存の資産を最大限活用しつつ、KMMフレームワークに依存しすぎな いよう、expect/actualはなるべく使わない方針。 どこを共通化するか
  29. AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャ 40 UseCase Adapter Interface

    Repository UseCase module Repository module Android/iOS Application KMM Application Service Service module Domain Domain module API Client API Client module Proto Proto module Repository Interface API Service Interface SDK Adapter Feature UILogic UI API Service API Service module
  30. AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャ 41 UseCase Adapter Interface

    Repository UseCase module Repository module Android/iOS Application KMM Application Service Service module Domain Domain module API Client API Client module Proto Proto module Repository Interface API Service Interface SDK Adapter Feature UILogic UI API Service API Service module
  31. AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャ 42 UseCase Adapter Interface

    Repository UseCase module Repository module Android/iOS Application KMM Application Service Service module Domain Domain module API Client API Client module Proto Proto module Repository Interface API Service Interface SDK Adapter Feature UILogic UI API Service API Service module 各プラットフォームと KMMのソースコードは別の Gitリポジトリで管理。 → バージョン管理の煩雑さから、 将来的にはモノレポ を目指す。
  32. AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャ 43 UseCase Adapter Interface

    Repository UseCase module Repository module Android/iOS Application KMM Application Service Service module Domain Domain module API Client API Client module Proto Proto module Repository Interface API Service Interface SDK Adapter Feature UILogic UI API Service API Service module
  33. AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャ 44 UseCase Adapter Interface

    Repository UseCase module Repository module Android/iOS Application KMM Application Service Service module Domain Domain module API Client API Client module Proto Proto module Repository Interface API Service Interface SDK Adapter Feature UILogic UI API Service API Service module 各機能ごとにUseCaseを作成。 アプリケーション全体で使用する UseCaseはServiceとして定義。 ServiceはさまざまなUseCaseから呼ばれ得る。
  34. AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャ 45 UseCase Adapter Interface

    Repository UseCase module Repository module Android/iOS Application KMM Application Service Service module Domain Domain module API Client API Client module Proto Proto module Repository Interface API Service Interface SDK Adapter Feature UILogic UI API Service API Service module
  35. AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャ 46 UseCase Adapter Interface

    Repository UseCase module Repository module Android/iOS Application KMM Application Service Service module Domain Domain module API Client API Client module Proto Proto module Repository Interface API Service Interface SDK Adapter Feature UILogic UI API Service API Service module DomainがRepositoryやAPIに関心を持たないようにしつつ、 UseCaseやServiceからRepositoryやAPIを呼び出せるよう、 interfaceをDomain moduleに定義。
  36. AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャ 47 UseCase Adapter Interface

    Repository UseCase module Repository module Android/iOS Application KMM Application Service Service module Domain Domain module API Client API Client module Proto Proto module Repository Interface API Service Interface SDK Adapter Feature UILogic UI API Service API Service module
  37. AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャ 48 UseCase Adapter Interface

    Repository UseCase module Repository module Android/iOS Application KMM Application Service Service module Domain Domain module API Client API Client module Proto Proto module Repository Interface API Service Interface SDK Adapter Feature UILogic UI API Service API Service module バージョン管理のために、 API ClientをラップするAPI Serviceを定義。 API Clientはprotocol bufferを返し、API ServiceでDomainに変換。
  38. AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャ 49 UseCase Adapter Interface

    Repository UseCase module Repository module Android/iOS Application KMM Application Service Service module Domain Domain module API Client API Client module Proto Proto module Repository Interface API Service Interface SDK Adapter Feature UILogic UI API Service API Service module
  39. AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャ 50 UseCase Adapter Interface

    Repository UseCase module Repository module Android/iOS Application KMM Application Service Service module Domain Domain module API Client API Client module Proto Proto module Repository Interface API Service Interface SDK Adapter Feature UILogic UI API Service API Service module KMMのライブラリがないSDKなどは、 RepositoryにAdapterを定義し、各アプリケーションで実装。 ログ、パフォーマンス計測機構や KMMへの移行に時間がかかる大きな Repositoryなど。
  40. AbemaTV, Inc. All Rights Reserved
 鈴木 大貴 Native Team所属。 ABEMAのモバイルアプリ開発及び

    マルチプラットフォームによる開発に従事。 51 波戸 勇二 國師 誠也 自己紹介 Native Team所属。 ABEMAモバイルアプリやテレビアプリ、 マルチプラットフォーム開発に従事。 Native Team所属。 Native Teamマネージャー兼クライアント戦略室 室長。
  41. AbemaTV, Inc. All Rights Reserved
 ios-mpp-2 ios-mpp-1 api-client-3 api-client-2 api-client-1

    55 バージョン管理 現状のリポジトリ構成 iOS向けに各モジュールをまとめたモジュールから Frameworkを生成し、成果物をダウンロードして Xcodeで利用する abema-ios abema-android abema-native ios-mpp.framework
  42. AbemaTV, Inc. All Rights Reserved
 ios-mpp-2 ios-mpp-1 api-client-3 api-client-2 api-client-1

    57 バージョン管理 現状のリポジトリ構成 Androidアプリのプロジェクトで KMMのリポジトリのAPIモジュールを指定して利用する abema-ios abema-android abema-native
  43. AbemaTV, Inc. All Rights Reserved
 UseCase Interface UseCase Repository ApiClient

    Domain 59 バージョン管理 マルチモジュールのバージョン管理 各モジュールごとにバージョニングされ、任意のモジュールでは依存するモジュールのバージョン解決が必要となる api-client-4 api-client-3 api-client-2 api-client-1 domain-3 domain-2 domain-1 repository-3 repository-2 repository-1 use-case-3 use-case-2 use-case-1 use-case-if-2 use-case-if-1
  44. AbemaTV, Inc. All Rights Reserved
 60 バージョン管理 マルチモジュールのバージョン管理 UseCaseモジュール自体は 1つなので、AndroidとiOSで任意の機能のみをバージョン指定することが困難となる

    UseCase Interface Repository ApiClient Domain api-client-4 api-client-3 api-client-2 api-client-1 domain-3 domain-2 domain-1 repository-3 repository-2 repository-1 use-case-if-2 use-case-if-1 UseCase use-case-3 use-case-2 use-case-1 Feature Bを実装 Feature Aを変更 Feature Aを実装 • Androidではv2のFeature Aの変更に対応済みで v3で追加したFeature Bの実装を取り込める • iOSではv2の変更の対応は後に実施したいが v3で追加したFeature Bの実装を先に使いたい
  45. AbemaTV, Inc. All Rights Reserved
 任意の機能をAndroid/iOSでバージョンを指定して利用可能とするために、 UseCaseをFeatureごとに分ける FeatureA UseCase I/F

    FeatureA UseCase Repository ApiClient Domain 61 バージョン管理 マルチモジュールで Featureを分けたバージョン管理 api-client-4 api-client-3 api-client-2 api-client-1 domain-3 domain-2 domain-1 repository-3 repository-2 repository-1 feature-a-2 feature-a-1 feature-b-if-2 feature-b-if-1 FeatureB UseCase I/F FeatureB UseCase feature-b-2 feature-b-1 feature-b-if-2 feature-b-if-1
  46. AbemaTV, Inc. All Rights Reserved
 feature-b-if-2 feature-b-if-1 feature-b-2 feature-b-1 FeatureAを更新する際に、

    Repository・Domain・ApiClientのバージョンをそれぞれ v3に更新した場合 FeatureA UseCase I/F FeatureA UseCase ApiClient Domain 62 バージョン管理 マルチモジュールで Featureを分けたバージョン管理 FeatureB UseCase I/F FeatureB UseCase Repository repository-3 repository-2 repository-1 feature-a-2 feature-a-1 feature-b-if-2 feature-b-if-1 api-client-4 api-client-3 api-client-2 api-client-1 domain-3 domain-2 domain-1
  47. AbemaTV, Inc. All Rights Reserved
 feature-b-if-2 feature-b-if-1 feature-a-2 feature-a-1 アプリ側でfeature-a-2を指定すると依存しているモジュールが

    v3になってしまい、 feature-b-1が壊れる FeatureA UseCase I/F FeatureA UseCase バージョン管理 マルチモジュールで Featureを分けたバージョン管理 Repository api-client-4 api-client-3 api-client-2 api-client-1 domain-3 domain-2 domain-1 ApiClient feature-b-if-2 feature-b-if-1 feature-b-2 feature-b-1 FeatureB UseCase I/F FeatureB UseCase Domain repository-3 repository-2 repository-1
  48. AbemaTV, Inc. All Rights Reserved
 UseCaseからドメインまで含んだ Featureと、共通Serviceとドメインを含んだ Coreに分けてバージョンを管理する 64 バージョン管理

    マルチモジュールで FeatureとCoreを分けたバージョン管理 FeatureA UseCase I/F FeatureA UseCase FeatureB UseCase I/F FeatureB UseCase FeatureA Repository FeatureA Domain FeatureB Repository FeatureB Domain Core Repository Core Domain ApiClient Service Service I/F feature-a-3 feature-a-2 feature-a-1 feature-a-2 feature-a-1 core-2 core-1 api-client-2 api-client-1
  49. AbemaTV, Inc. All Rights Reserved
 feature-a-2 feature-a-1 feature-a-3 feature-a-2 feature-a-1

    UseCaseからドメインまで含んだ Featureと、共通Serviceとドメインを含んだ Coreに分けてバージョンを管理する 65 バージョン管理 マルチモジュールで FeatureとCoreを分けたバージョン管理 FeatureA UseCase I/F FeatureA UseCase FeatureB UseCase I/F FeatureB UseCase FeatureA Repository FeatureA Domain FeatureB Repository FeatureB Domain Service I/F Core Repository Core Domain ApiClient Service core-2 core-1 api-client-2 api-client-1 「Featureで管理するドメイン」と「 Coreで管理するドメイン」 に分けることでドメインの変更による影響範囲が明確にな るため、Featureごとにバージョニングしても壊れにくい状 態にできる
  50. AbemaTV, Inc. All Rights Reserved
 66 バージョン管理 マルチモジュールで FeatureとCoreを分けたバージョン管理 FeatureA

    UseCase I/F FeatureA UseCase FeatureB UseCase I/F FeatureB UseCase FeatureA Repository FeatureA Domain FeatureB Repository FeatureB Domain Core Repository Core Domain ApiClient Service Service I/F ApiClientを更新した場合は以降依存モジュール、 Coreを更新した場合は全 Featureを更新する運用が必要になる feature-a-3 feature-a-2 feature-a-1 feature-a-2 feature-a-1 core-2 core-1 api-client-2 api-client-1
  51. AbemaTV, Inc. All Rights Reserved
 • モジュールがアップロードが完了するまで次のモジュールの作業ができない ◦ モジュールの実装ごとにPRを投げ、マージのタイミングでリリース処理を実行している ◦

    アップロードが完了すると、次のモジュールの build.gradle.ktsに任意のバージョンを指定してGradle Sync をすることで利用可能になる • iOS向けにまとめるモジュールがあることでAndroidよりもPRが1回多くなっている ◦ 利用したい全モジュールがバージョン指定できるようになったタイミングでバージョンを修正して PRを投げ、 マージのタイミングでframework生成のコマンドを実行して任意の Releaseに成果物を添付している バージョン管理 67 今後の課題
  52. AbemaTV, Inc. All Rights Reserved
 • モジュールがアップロードが完了するまで次のモジュールの作業ができない ◦ モジュールの実装ごとにPRを投げ、マージのタイミングでリリース処理を実行している ◦

    アップロードが完了すると、次のモジュールの build.gradle.ktsに任意のバージョンを指定してGradle Sync をすることで利用可能になる • iOS向けにまとめるモジュールがあることでAndroidよりもPRが1回多くなっている ◦ 利用したい全モジュールがバージョン指定できるようになったタイミングでバージョンを修正して PRを投げ、 マージのタイミングでframework生成のコマンドを実行して任意の Releaseに成果物を添付している バージョン管理 68 今後の課題
  53. AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャがアプリ側のリアーキテクチャをベースにしているため、一見置き換えが容易に見える 70 既存アプリの移行 アプリのUseCase以降の層をKMMのUseCase以降の層に置き換える UI

    UI Logic UI Layer UseCase DB API Domain Repository Domain Layer Application Layer Data Layer UseCase Adapter API Domain Repository FeatureA UseCase Adapter API Domain Repository FeatureB Core Domain UseCase Repository API Adapter
  54. AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャがアプリ側のリアーキテクチャをベースにしているため、一見置き換えが容易に見える 71 既存アプリの移行 アプリのUseCase以降の層をKMMのUseCase以降の層に置き換える UI

    UI Logic UI Layer DB API Domain Repository Domain Layer Data Layer Adapter API Domain Repository UseCase Adapter API Domain Repository FeatureB Core Domain UseCase Repository API Adapter UseCase FeatureA UseCase Application Layer UseCaseを置き換え、UseCaseImplが依存している RepositoryのInterfaceのImplを注入できるようにする
  55. AbemaTV, Inc. All Rights Reserved
 • AndroidとiOSでアーキテクチャは揃っていたが定義の単位が異なる部分がある ◦ 該当箇所の実装担当者にヒアリングをし、 KMMで実装するための方針を整理

    ◦ クラス単位で実装が異なる場合はそれぞれで対応するクラスを整理し、実装方針を策定 • UseCaseImplに注入するRepositoryを現段階でKMM側で実装し切れない ◦ KMM側ではI/Fのみを定義し、アプリ側の既存 RepositoryとInterfaceを適合させるアダプタを実 装する ◦ iOS側ではPublisherやObservableをFlowに変換するアダプタを別途実装が必要になる 既存アプリの移行 72 課題
  56. AbemaTV, Inc. All Rights Reserved
 既存アプリの移行 (差異の例) 73 fun getCanRegisterManager(isTablet:

    Boolean): Boolean { return ContentPreviewUtil.canRegisterManager( isTablet = isTablet, isJapanRegion = regionStore.isJapan(), ) } fun toggleLockManager(isTvPlayable: Boolean): Boolean { return ContentPreviewUtil.shouldLockManager( isTvPlayable = isTvPlayable, networkState = systemStore.networkState, mode = userStore.contentPreviewAutoPlayMode.value, ) } func observeContentPreviewable() -> Observable<Bool> { return Observable.combineLatest( reachabilityRepository.observeNetworkType(), settingContentPreviewRepository.observeSetting(), regionRepository.observeRegionPolicy() ) .map { networkType, setting, regionPolicy -> Bool in ... } .distinctUntilChanged() } Android iOS
  57. AbemaTV, Inc. All Rights Reserved
 既存アプリの移行 (差異の例) 74 fun getCanRegisterManager(isTablet:

    Boolean): Boolean { return ContentPreviewUtil.canRegisterManager( isTablet = isTablet, isJapanRegion = regionStore.isJapan(), ) } fun toggleLockManager(isTvPlayable: Boolean): Boolean { return ContentPreviewUtil.shouldLockManager( isTvPlayable = isTvPlayable, networkState = systemStore.networkState, mode = userStore.contentPreviewAutoPlayMode.value, ) } func observeContentPreviewable() -> Observable<Bool> { return Observable.combineLatest( reachabilityRepository.observeNetworkType(), settingContentPreviewRepository.observeSetting(), regionRepository.observeRegionPolicy() ) .map { networkType, setting, regionPolicy -> Bool in ... } .distinctUntilChanged() } Android iOS 任意の処理の結果を返す関数が 1つ存在し 処理は非同期実行される
  58. AbemaTV, Inc. All Rights Reserved
 既存アプリの移行 (差異の例) 75 fun getCanRegisterManager(isTablet:

    Boolean): Boolean { return ContentPreviewUtil.canRegisterManager( isTablet = isTablet, isJapanRegion = regionStore.isJapan(), ) } fun toggleLockManager(isTvPlayable: Boolean): Boolean { return ContentPreviewUtil.shouldLockManager( isTvPlayable = isTvPlayable, networkState = systemStore.networkState, mode = userStore.contentPreviewAutoPlayMode.value, ) } func observeContentPreviewable() -> Observable<Bool> { return Observable.combineLatest( reachabilityRepository.observeNetworkType(), settingContentPreviewRepository.observeSetting(), regionRepository.observeRegionPolicy() ) .map { networkType, setting, regionPolicy -> Bool in ... } .distinctUntilChanged() } Android iOS iOSと同等の処理が 2つの関数に分かれており 処理は同期実行される
  59. AbemaTV, Inc. All Rights Reserved
 既存アプリの移行 (差異の例) 76 fun getCanRegisterManager(isTablet:

    Boolean): Boolean { return ContentPreviewUtil.canRegisterManager( isTablet = isTablet, isJapanRegion = regionStore.isJapan(), ) } fun toggleLockManager(isTvPlayable: Boolean): Boolean { return ContentPreviewUtil.shouldLockManager( isTvPlayable = isTvPlayable, networkState = systemStore.networkState, mode = userStore.contentPreviewAutoPlayMode.value, ) } func observeContentPreviewable() -> Observable<Bool> { return Observable.combineLatest( reachabilityRepository.observeNetworkType(), settingContentPreviewRepository.observeSetting(), regionRepository.observeRegionPolicy() ) .map { networkType, setting, regionPolicy -> Bool in ... } .distinctUntilChanged() } Android iOS
  60. AbemaTV, Inc. All Rights Reserved
 既存アプリの移行 (差異の例) 77 fun getCanRegisterManager(isTablet:

    Boolean): Boolean { return ContentPreviewUtil.canRegisterManager( isTablet = isTablet, isJapanRegion = regionStore.isJapan(), ) } fun toggleLockManager(isTvPlayable: Boolean): Boolean { return ContentPreviewUtil.shouldLockManager( isTvPlayable = isTvPlayable, networkState = systemStore.networkState, mode = userStore.contentPreviewAutoPlayMode.value, ) } func observeContentPreviewable() -> Observable<Bool> { return Observable.combineLatest( reachabilityRepository.observeNetworkType(), settingContentPreviewRepository.observeSetting(), regionRepository.observeRegionPolicy() ) .map { networkType, setting, regionPolicy -> Bool in ... } .distinctUntilChanged() } Android iOS fun observeContentPreviewable(): Flow<Boolean> { return combine( networkRepository.observeNetworkState(), settingContentPreviewRepository.observeSetting(), regionRepository.observeRegionPolicy() ){ networkState, setting, regionPolicy -> … } … } KMM コードリーディング + 該当範囲の担当に実装についての ヒアリングを実施し、両 OSのUILogicでの影響も考慮した 上でKMM側のI/Fを決めて実装を進める
  61. AbemaTV, Inc. All Rights Reserved
 • AndroidとiOSでアーキテクチャは揃っていたが定義の単位が異なる部分がある ◦ 該当箇所の実装担当者にヒアリングをし、 KMMで実装するための方針を整理

    ◦ クラス単位で実装が異なる場合はそれぞれで対応するクラスを整理し、実装方針を策定 • UseCaseImplに注入するRepositoryを現段階でKMM側で実装し切れない ◦ KMM側ではI/Fのみを定義し、アプリ側の既存 RepositoryとInterfaceを適合させるアダプタを実 装する ◦ iOS側ではPublisherやObservableをFlowに変換するアダプタを別途実装が必要になる 既存アプリの移行 78 課題
  62. AbemaTV, Inc. All Rights Reserved
 • Playgroundを作成 ◦ KMMのRepositoryで実装したものを、アプリに導入する前に事前に確認できる •

    チュートリアルプロジェクトを作成 ◦ 移行途中のAndroidとiOSのサンプルプロジェクトを作成し、模擬移行を PRベースで実施 ◦ 講義・実習形式でメンバーへのインストールを検討 • Contributingのガイドラインの作成 Mobile Appチームへの普及 80 今後やっていくこと
  63. AbemaTV, Inc. All Rights Reserved
 82 全体戦略 Desktop Browser Android

    Web Unity Mobile Browser Mobile App Smart Display/ Speaker TV iOS iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Amazon Fire TV Amazon FIre Tablet Mobile Web ユースケース 技術スタック 再掲
  64. AbemaTV, Inc. All Rights Reserved
 83 全体戦略 Desktop Browser Android

    Web Unity Mobile Browser Mobile App Smart Display/ Speaker TV iOS iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Amazon Fire TV Amazon FIre Tablet Mobile Web ユースケース 技術スタック 全クライアントで汎化できる Entityの共通化
  65. AbemaTV, Inc. All Rights Reserved
 84 全体戦略 Desktop Browser Android

    Web Unity Mobile Browser Mobile App Smart Display/ Speaker TV iOS iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Amazon Fire TV Amazon FIre Tablet Mobile Web ユースケース 技術スタック Player、platform-specificな部分の共通化
  66. AbemaTV, Inc. All Rights Reserved
 85 全体戦略 Desktop Browser Android

    Web Unity Mobile Browser Mobile App Smart Display/ Speaker TV iOS iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Amazon Fire TV Amazon FIre Tablet Mobile Web ユースケース 技術スタック Player、platform-specificな部分の共通化
  67. AbemaTV, Inc. All Rights Reserved
 86 全体戦略 Desktop Browser Android

    Web Unity Mobile Browser Mobile App Smart Display/ Speaker TV iOS iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Amazon Fire TV Amazon FIre Tablet Mobile Web ユースケース 技術スタック Player、platform-specificな 部分の共通化
  68. AbemaTV, Inc. All Rights Reserved
 87 全体戦略 Desktop Browser Android

    Web Unity Mobile Browser Mobile App Smart Display/ Speaker TV iOS iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Amazon Fire TV Amazon FIre Tablet Mobile Web ユースケース 技術スタック UseCase、Entityの共通化 ※ platform-specificなAPIも部分的に共通化可能
  69. AbemaTV, Inc. All Rights Reserved
 88 全体戦略 Desktop Browser Android

    Web Unity Mobile Browser Mobile App Smart Display/ Speaker TV iOS iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Amazon Fire TV Amazon FIre Tablet Mobile Web ユースケース 技術スタック UseCase、Entityの共通化 ※ platform-specificなAPIも部分的に共通化可能
  70. AbemaTV, Inc. All Rights Reserved
 全体戦略 89 Use Cases Entities

    UI Presentation DB platform-specific APIs External Interfaces Gateways Presenters Controllers Platform Common UI / Presenters / Controllers Desktop Browser UseCases Android Web Unity Mobile App UseCases Mobile Browser UseCases Smart Display/Speaker UseCases TV UseCases iOS iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Mobile Web Common Entities Multi Platform Common Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature API DB Purchase Log etc Purchase Purchase etc etc etc Player Player Player Domain Service Domain service Domain Object Domain Object Domain Object Value Object Value Object Value Object Domain Service Feature Feature Kotlin MPP
  71. AbemaTV, Inc. All Rights Reserved
 全体戦略 90 Use Cases UI

    Presentation DB platform-specific APIs External Interfaces Gateways Presenters Controllers Platform Common UI / Presenters / Controllers Desktop Browser UseCases Android Web Unity Mobile App UseCases Mobile Browser UseCases Smart Display/Speaker UseCases TV UseCases iOS iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Mobile Web Multi Platform Common Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature API DB Purchase Log etc Purchase Purchase etc etc etc Player Player Player Feature Feature Kotlin MPP 全クライアントで汎化できる Entityの共通化 Common Entities Domain Service Domain service Domain Object Domain Object Domain Object Value Object Value Object Value Object Domain Service Entities
  72. AbemaTV, Inc. All Rights Reserved
 Kotlin MPP Common Entities Domain

    Service Domain service Domain Object Domain Object Domain Object Value Object Value Object Value Object Domain Service 全体戦略 91 UI Presentation DB platform-specific APIs External Interfaces UI / Presenters / Controllers Desktop Browser UseCases Mobile App UseCases Mobile Browser UseCases Smart Display/Speaker UseCases TV UseCases iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Mobile Web Multi Platform Common Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature API DB Log etc Feature Feature Unity Platform Common Purchase Purchase Purchase etc etc etc Player Player Player Player、platform-specificな 部分の共通化 Android Web iOS Use Cases Gateways Presenters Controllers Entities
  73. AbemaTV, Inc. All Rights Reserved
 Platform Common Purchase Purchase Purchase

    etc etc etc Player Player Player Common Entities Domain Service Domain service Domain Object Domain Object Domain Object Value Object Value Object Value Object Domain Service 全体戦略 92 UI Presentation DB platform-specific APIs External Interfaces Gateways Presenters Controllers UI / Presenters / Controllers Desktop Browser UseCases Mobile Browser UseCases Smart Display/Speaker UseCases iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Mobile Web Multi Platform Common Feature Feature Feature Feature Feature Feature Feature Feature Feature API DB Log etc Android Web Unity iOS Mobile App UseCases TV UseCases Feature Feature Feature Feature Feature Feature Feature Feature UseCase、Entityの共通化 Kotlin MPP Use Cases Entities
  74. AbemaTV, Inc. All Rights Reserved
 Common Entities Domain Service Domain

    service Domain Object Domain Object Domain Object Value Object Value Object Value Object Domain Service 全体戦略 93 UI Presentation DB platform-specific APIs External Interfaces UI / Presenters / Controllers Desktop Browser UseCases Mobile App UseCases Mobile Browser UseCases Smart Display/Speaker UseCases TV UseCases iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Mobile Web Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Unity Platform Common Purchase Purchase Purchase etc etc etc Player Player Player Android Web iOS Use Cases Gateways Presenters Controllers Entities Multi Platform Common API DB Log etc Kotlin MPP APIやDB、ログなど外部IFの共通化 ※ 適用できないPFもあり
  75. AbemaTV, Inc. All Rights Reserved
 全体戦略 94 Platform Common UI

    / Presenters / Controllers Desktop Browser UseCases Mobile App UseCases Mobile Browser UseCases Smart Display/Speaker UseCases TV UseCases iOS Mobile Android Mobile PC Web Chrome cast Apple TV Android TV IPTV Google Nest Hub Game Console Mobile Web Common Entities Multi Platform Common Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature API DB Purchase Log etc Purchase Purchase etc etc etc Player Player Player Domain Service Domain service Domain Object Domain Object Domain Object Value Object Value Object Value Object Domain Service Feature Feature • クライアント全体でのEntityの共通化 • プラットフォーム軸での共通化 • ユースケース軸での共通化 • 外部IFの共通化 • モジュラアーキテクチャによる再利用性の促進 • モジュールのバージョン管理と開発フローの構築 • マルチプラットフォーム・クロスプラットフォーム技術の進化への追随