Slide 1

Slide 1 text

AbemaTV, Inc. All Rights Reserved
 1

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

AbemaTV, Inc. All Rights Reserved
 4 1. 対応デバイスの拡大 2. MobileAppが抱えていた課題 3. リアーキテクチャ 4. KMMのアーキテクチャ 5. バージョン管理 INDEX 6. 既存アプリの移行 7. MobileAppチームへの普及 8. 全体戦略

Slide 5

Slide 5 text

AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 5

Slide 6

Slide 6 text

AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 6 2016年4月11日に開局した当初は、対応デバイスとして iOS・Android (mobile) とブラウザ (pc / mobile) からスタート。 2016年4月 開局 iOS mobile Android mobile Web pc / mobile

Slide 7

Slide 7 text

AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 7 2016年中には当時の主要なテレビデバイスのプラットフォームに順次対応。 2016年 2016/08 Apple TV Android TV Chrome cast 2016/11 2016/12 2016/10 Amazon Fire TV

Slide 8

Slide 8 text

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はサポート終了

Slide 9

Slide 9 text

AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 9 2021年にはにはGoogle Nest HubとNintendo Switchに対応。 2021年 Game Console Google Nest Hub 2021/12 2021/06

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 11 ● 対応デバイスが増えるのに比例して開発リソースが必要 ● 優先度の高いデバイスに開発リソースが偏り、機能差がある ● デバイス間で意図しない仕様・実装差異や品質のバラつきがある ● レガシーなアプリケーションのメンテナンスコストが高くなる 課題

Slide 12

Slide 12 text

AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 12 ● デバイスの特性にあわせたユースケースのグルーピングをして対応デバイスの拡 大に正比例しない開発体制の構築 ● 汎化可能な領域と特化する領域を定め、コードの共通化と再利用性の促進 アプローチ

Slide 13

Slide 13 text

AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 13 デバイスのユースケースにあわせたグルーピング。 ユースケース Desktop Browser Mobile Browser Mobile App Smart Display/ Speaker TV

Slide 14

Slide 14 text

AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 14 技術スタックは大きく分けて iOS, Android, Web, Unity。 技術スタック (プラットフォーム) Android Web Unity iOS ※ Amazon AlexaはAWS Lambdaですがここではスコープ外としています

Slide 15

Slide 15 text

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 再掲

Slide 16

Slide 16 text

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 ユースケース 技術スタック

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

AbemaTV, Inc. All Rights Reserved
 対応デバイスの拡大 18 汎化と特化 Use Cases Entities UI Presentation DB platform-specific APIs External Interfaces Gateways Presenters Controllers 特化 汎化 ● 特化する部分 ○ プレゼンテーション層 ○ プラットフォーム固有のエンティティ・ユー スケース ● 汎化する部分 ○ 汎化された外部IF ○ プラットフォームに依存しないエンティティ ・ユースケース

Slide 19

Slide 19 text

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 マルチプラットフォーム・クロスプラットフォームツールの検討

Slide 20

Slide 20 text

AbemaTV, Inc. All Rights Reserved
 ● プラットフォームに特化した最適なUI/UXの提供 ● プラットフォームAPIへの追従性 ● 開発コミュニティの将来性 ● 快適な開発体験 対応デバイスの拡大 20 マルチプラットフォーム・クロスプラットフォームツールの検討

Slide 21

Slide 21 text

AbemaTV, Inc. All Rights Reserved
 UIを含むコードの共通化は各プラットフォームに最適なUI/UXの提供が難しい部分 が大きく、モバイルだけでなくクライアントアプリケーション全体のスコープで考え、 ABEMAのUI/UXの要求を満たすことができないと判断。 開発やコミュニティ状況、将来性とDeveloper Experienceを鑑みて現時点でビジ ネスロジックの共通化を目的としてKotlin Multiplatformを採用。 ※ UnityによるUIを含めた共通化も検証中 対応デバイスの拡大 21 マルチプラットフォーム・クロスプラットフォームツールの検討

Slide 22

Slide 22 text

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 開発体制

Slide 23

Slide 23 text

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 開発体制

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

AbemaTV, Inc. All Rights Reserved
 Mobile Appが抱えていた課題 25

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

AbemaTV, Inc. All Rights Reserved
 リアーキテクチャ 30

Slide 31

Slide 31 text

AbemaTV, Inc. All Rights Reserved
 ● ロジックの置き場所が設計によって担保されない ○ プラットフォーム間共通のビジネスロジックの分離が困 難 ○ テスタビリティ・メンテナビリティの低いコードの増加 ○ 密結合なコンポーネントによってビルド時間の増加、個 別のビルドが困難 課題 リアーキテクチャ 31 Meta Platforms(旧Facebook)社が提唱したクライアントウェ ブアプリケーションのアーキテクチャ。 ABEMA開局当初(2016年)から採用。 Flux https://facebook.github.io/flux/docs/in-depth-overview

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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 ドメイン層

Slide 34

Slide 34 text

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 アプリケーション層

Slide 35

Slide 35 text

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 ・ドメインロジックやアプリケーションロジック ・リポジトリから他のリポジトリの呼び出し データ層

Slide 36

Slide 36 text

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層

Slide 37

Slide 37 text

AbemaTV, Inc. All Rights Reserved
 リアーキテクチャ 37 もっと詳しい話 https://developers.cyberagent.co.jp/blog/archives/29967/

Slide 38

Slide 38 text

AbemaTV, Inc. All Rights Reserved
 KMMのアーキテクチャ 38

Slide 39

Slide 39 text

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はなるべく使わない方針。 どこを共通化するか

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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リポジトリで管理。 → バージョン管理の煩雑さから、 将来的にはモノレポ を目指す。

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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から呼ばれ得る。

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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に定義。

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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に変換。

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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など。

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

AbemaTV, Inc. All Rights Reserved
 バージョン管理 52

Slide 53

Slide 53 text

AbemaTV, Inc. All Rights Reserved
 53 バージョン管理 現状のリポジトリ構成 AndroidとiOSのプロジェクトを別リポジトリで管理しているため、 KMMのリポジトリも別で管理している abema-ios abema-android abema-native

Slide 54

Slide 54 text

AbemaTV, Inc. All Rights Reserved
 54 バージョン管理 現状のリポジトリ構成 KMMのリポジトリでは APIモジュールとiOS向けに各モジュールをまとめるモジュールを管理している abema-ios abema-android abema-native ios-mpp-2 ios-mpp-1 api-client-3 api-client-2 api-client-1

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

AbemaTV, Inc. All Rights Reserved
 56 iOS向けのFrameworkを配布する機構に関する過去の登壇資料 https://speakerdeck.com/martysuzuki/iosnikmmwodao-ru-surutips 現状のリポジトリ構成

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

AbemaTV, Inc. All Rights Reserved
 58 バージョン管理 モジュールが増えていくと バージョン管理はどうなっていくか?

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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の実装を先に使いたい

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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ごとにバージョニングしても壊れにくい状 態にできる

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

AbemaTV, Inc. All Rights Reserved
 既存アプリの移行 69

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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を注入できるようにする

Slide 72

Slide 72 text

AbemaTV, Inc. All Rights Reserved
 ● AndroidとiOSでアーキテクチャは揃っていたが定義の単位が異なる部分がある ○ 該当箇所の実装担当者にヒアリングをし、 KMMで実装するための方針を整理 ○ クラス単位で実装が異なる場合はそれぞれで対応するクラスを整理し、実装方針を策定 ● UseCaseImplに注入するRepositoryを現段階でKMM側で実装し切れない ○ KMM側ではI/Fのみを定義し、アプリ側の既存 RepositoryとInterfaceを適合させるアダプタを実 装する ○ iOS側ではPublisherやObservableをFlowに変換するアダプタを別途実装が必要になる 既存アプリの移行 72 課題

Slide 73

Slide 73 text

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 { return Observable.combineLatest( reachabilityRepository.observeNetworkType(), settingContentPreviewRepository.observeSetting(), regionRepository.observeRegionPolicy() ) .map { networkType, setting, regionPolicy -> Bool in ... } .distinctUntilChanged() } Android iOS

Slide 74

Slide 74 text

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 { return Observable.combineLatest( reachabilityRepository.observeNetworkType(), settingContentPreviewRepository.observeSetting(), regionRepository.observeRegionPolicy() ) .map { networkType, setting, regionPolicy -> Bool in ... } .distinctUntilChanged() } Android iOS 任意の処理の結果を返す関数が 1つ存在し 処理は非同期実行される

Slide 75

Slide 75 text

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 { return Observable.combineLatest( reachabilityRepository.observeNetworkType(), settingContentPreviewRepository.observeSetting(), regionRepository.observeRegionPolicy() ) .map { networkType, setting, regionPolicy -> Bool in ... } .distinctUntilChanged() } Android iOS iOSと同等の処理が 2つの関数に分かれており 処理は同期実行される

Slide 76

Slide 76 text

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 { return Observable.combineLatest( reachabilityRepository.observeNetworkType(), settingContentPreviewRepository.observeSetting(), regionRepository.observeRegionPolicy() ) .map { networkType, setting, regionPolicy -> Bool in ... } .distinctUntilChanged() } Android iOS

Slide 77

Slide 77 text

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 { return Observable.combineLatest( reachabilityRepository.observeNetworkType(), settingContentPreviewRepository.observeSetting(), regionRepository.observeRegionPolicy() ) .map { networkType, setting, regionPolicy -> Bool in ... } .distinctUntilChanged() } Android iOS fun observeContentPreviewable(): Flow { return combine( networkRepository.observeNetworkState(), settingContentPreviewRepository.observeSetting(), regionRepository.observeRegionPolicy() ){ networkState, setting, regionPolicy -> … } … } KMM コードリーディング + 該当範囲の担当に実装についての ヒアリングを実施し、両 OSのUILogicでの影響も考慮した 上でKMM側のI/Fを決めて実装を進める

Slide 78

Slide 78 text

AbemaTV, Inc. All Rights Reserved
 ● AndroidとiOSでアーキテクチャは揃っていたが定義の単位が異なる部分がある ○ 該当箇所の実装担当者にヒアリングをし、 KMMで実装するための方針を整理 ○ クラス単位で実装が異なる場合はそれぞれで対応するクラスを整理し、実装方針を策定 ● UseCaseImplに注入するRepositoryを現段階でKMM側で実装し切れない ○ KMM側ではI/Fのみを定義し、アプリ側の既存 RepositoryとInterfaceを適合させるアダプタを実 装する ○ iOS側ではPublisherやObservableをFlowに変換するアダプタを別途実装が必要になる 既存アプリの移行 78 課題

Slide 79

Slide 79 text

AbemaTV, Inc. All Rights Reserved
 Mobile Appチームへの普及 79

Slide 80

Slide 80 text

AbemaTV, Inc. All Rights Reserved
 ● Playgroundを作成 ○ KMMのRepositoryで実装したものを、アプリに導入する前に事前に確認できる ● チュートリアルプロジェクトを作成 ○ 移行途中のAndroidとiOSのサンプルプロジェクトを作成し、模擬移行を PRベースで実施 ○ 講義・実習形式でメンバーへのインストールを検討 ● Contributingのガイドラインの作成 Mobile Appチームへの普及 80 今後やっていくこと

Slide 81

Slide 81 text

AbemaTV, Inc. All Rights Reserved
 全体戦略 81

Slide 82

Slide 82 text

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 ユースケース 技術スタック 再掲

Slide 83

Slide 83 text

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の共通化

Slide 84

Slide 84 text

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な部分の共通化

Slide 85

Slide 85 text

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な部分の共通化

Slide 86

Slide 86 text

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な 部分の共通化

Slide 87

Slide 87 text

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も部分的に共通化可能

Slide 88

Slide 88 text

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も部分的に共通化可能

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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もあり

Slide 94

Slide 94 text

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の共通化 ● モジュラアーキテクチャによる再利用性の促進 ● モジュールのバージョン管理と開発フローの構築 ● マルチプラットフォーム・クロスプラットフォーム技術の進化への追随

Slide 95

Slide 95 text

AbemaTV, Inc. All Rights Reserved