Share
Embed
Transcript
104 slides
-
ABEMAのKotlin Multiplatform / / Flutter × Kotlin Multiplatform by CyberAgent
# Takahiro Menju / takahirom -
About me Takahiro Menju takahirom(@new_runnable) ABEMA Android DroidKaigi Conference App
Leader Google Developers Expert for Android DroidKaigi/conference-app- まだまだ活発に開発しているので お待ちしてます🙏 -
ABEMAのマルチデバイス対応 • Android • iOS • Android TV • Apple
TV https://abema.tv/supported-device -
ABEMAのマルチデバイス対応 • Android • iOS • Android TV • Apple
TV • Amazon Echo https://abema.tv/supported-device -
ABEMAのマルチデバイス対応 • Android • iOS • Android TV • Apple
TV • Amazon Echo • などなど https://abema.tv/supported-device -
Kotlin Multiplatform • Kotlinで書かれたコードを、複数の プラットフォームで動作させる仕組み • 例えばSwiftのコードからKotlinで書かれた コードの実装を呼び出すことができる Multiplatform programming
https://kotlinlang.org/docs/multiplatform.html -
⽅向性を提案する • ⽬的と課題を設定 • “クライアント全体としての開発の⾼速化と継続的な機能提供” • アプローチを⽐較する • Flutter、React Native、Kotlin
Multiplatformなどを⽐較 • ⽅向性を⽰す -
⽅向性を提案する • ⽬的と課題を設定 • “クライアント全体としての開発の⾼速化と継続的な機能提供” • アプローチを⽐較する • Flutter、React Native、Kotlin
Multiplatformなどを⽐較 • ⽅向性を⽰す • ロジックを共有できるUI / UX観点と開発やコミュニティ状況、 DXと将来性を鑑みて、現時点の⽅向としてKotlin Multiplatformを採⽤する提案を⾏った(by Yuji Hato @dekatotoro) -
参考になるもの 公式のケーススタディ https://kotlinlang.org/lp/mobile/case-studies/ ビジネス的な視点がもっと必要があるなら以下が参考になる。 Building a Business Case for Kotlin
Multiplatform & Mobile Code Sharing https://dev.to/touchlab/building-a-business-case-for-kotlin-multiplatform-mobile-code- sharing- m -
CE(Consumer Electronics)チーム • Kotlin Multiplatformを使って設計を強制するというものを検 討中 • Kotlin MultiplatformでUseCase、Entityなどを実装 •
Data層やUI層は各プラットフォームで実装する → これから導⼊して経過を⾒ていく UI UseCase / Entity Data Kotlin Multiplatform Platfrom Platfrom 簡略図 -
WEBチーム • Kotlin Multiplatformの検証中 • Playgroundのリポジトリを作って検証 • いくつかの技術的な問題があり未導⼊ • TypeScriptの定義で、enumが使えない
• https://youtrack.jetbrains.com/issue/KT- • https://youtrack.jetbrains.com/issue/KT- • Ktorのサイズ⼤きい • https://youtrack.jetbrains.com/issue/KTOR- • など • 少しずつ改善されていこうとしている。 -
Nativeチームの⾛り始め • Domain Objectを共通化できないか? • そもそも設計の段階で結構話し合いが⼤変になっていた😂 • iOS、Androidの既存のアーキテクチャの違い、 Repositoryの範囲は?どこまでUseCase?Entityを interfaceとdefault
functionを使って分ける?Entity化 はどこからするか? → どうしようか。。 -
なぜAPIクライアントから導⼊したか • 同じサーバーを使っているので、iOSとAndroidの実装差異が少ないた め、議論が発⽣しにくい。そのため、スムーズに実装できる • 実績ができるので他の部分への導⼊も進みやすくなる • 共通化できる部分が多く、今後も活かせる • APIの定義
リクエストやレスポンスのオブジェクト • APIのヘッダーなどの設定、エラーなどの処理 -
なぜAPIクライアントから導⼊したか • 同じサーバーを使っているので、iOSとAndroidの実装差異が少ないた め、議論が発⽣しにくい。そのため、スムーズに実装できる • 実績ができるので他の部分への導⼊も進みやすくなる • 共通化できる部分が多く、今後も活かせる • APIの定義
リクエストやレスポンスのオブジェクト • APIのヘッダーなどの設定、エラーなどの処理 • FakeのAPI実装、テストや、まだAPI実装がないときに共通の Fakeを使ってクライアントで開発することができる。 -
なぜAPIクライアントから導⼊したか • 同じサーバーを使っているので、iOSとAndroidの実装差異が少ないた め、議論が発⽣しにくい。そのため、スムーズに実装できる • 実績ができるので他の部分への導⼊も進みやすくなる • 共通化できる部分が多く、今後も活かせる • APIの定義
リクエストやレスポンスのオブジェクト • APIのヘッダーなどの設定、エラーなどの処理 • FakeのAPI実装、テストや、まだAPI実装がないときに共通の Fakeを使ってクライアントで開発することができる。 • 将来的にAPIのレスポンスのEntityからドメインオブジェクトへの変 換もできる。 -
チームで⾏う3つのアプローチ • . AndroidチームがMultiplatformのモ ジュールを開発する。iOSの開発者はブ ラックボックスとして扱う Approaches to organizing teamwork
for Multiplatform projects https://kotlinlang.org/docs/mobile/organize-process-around-kmm.html#approaches-to- organizing-teamwork-for-multiplatform-projects -
チームで⾏う3つのアプローチ • . AndroidチームがMultiplatformのモ ジュールを開発する。iOSの開発者はブ ラックボックスとして扱う • . AndroidとiOS両⽅がマルチプラット フォームライブラリで同時に作業する
Approaches to organizing teamwork for Multiplatform projects https://kotlinlang.org/docs/mobile/organize-process-around-kmm.html#approaches-to- organizing-teamwork-for-multiplatform-projects -
チームで⾏う3つのアプローチ • . AndroidチームがMultiplatformのモ ジュールを開発する。iOSの開発者はブ ラックボックスとして扱う • . AndroidとiOS両⽅がマルチプラット フォームライブラリで同時に作業する
• 3. マルチプラットフォームライブラリの作 業は専⽤チームが⾏う Approaches to organizing teamwork for Multiplatform projects https://kotlinlang.org/docs/mobile/organize-process-around-kmm.html#approaches-to- organizing-teamwork-for-multiplatform-projects -
. AndroidとiOS両⽅がマルチプラットフォームライブラリで同時 に作業する • 今のNativeチームにマッチしている。✅ • 問題となるのは学習コスト。 • Android iOSエンジニアがお互いの技術を学ぶ
Bootcampを⾏っており、ある程度のKotlinの知識が 浸透していた。✅ • 引き続き学習していく仕組みを整える必要がありそう -
ABEMAでの現在のアプローチ • ” .AndroidチームがMultiplatformのモジュールを開発する戦 略”を⾏い、 • ” . AndroidとiOS両⽅がマルチプラットフォームライブラリで 同時に作業する”に移⾏していく形
• AndroidのエンジニアのほうがKotlinやGradleに慣れている • iOSエンジニアが意外とKotlin Multiplatformに興味があって 良かった(良いチーム) -
Kotlin Multiplatform Project 現在の構成 proto Android project apiclient apiclient-fake iOS
project ios-abema-mpp -
Kotlin Multiplatform Project proto Android project apiclient apiclient-fake iOS project
ios-abema-mpp Android, iOS, Kotlin Multiplatformで リポジトリを分けて管理 (これは現在の状態からの移⾏のしやすさからこうなっている) Androidプロジェクト GitHub リポジトリ iOSプロジェクト GitHub リポジトリ Kotlin Multiplatform Project GitHub リポジトリ -
Kotlin Multiplatform Project proto Android project apiclient apiclient-fake iOS project
ios-abema-mpp 細かくモジュールを分けている -
Kotlin Multiplatform Project proto Android project apiclient apiclient-fake iOS project
ios-abema-mpp Wire を利⽤し、Protocol Buffersの定義ファイルから ⽣成されたコードを置いている Ktor Clientを使ったAPI Client テストダブルやプロトタイプ実装 で使うfake iOS⽤のライブラリ 技術的詳細 -
Kotlin Multiplatform Project proto Android project apiclient apiclient-fake iOS project
ios-mpp Web Ktorのサイズが⼤きくて⼊れられない さまざまなプラットフォームでの導⼊を想定したときに⼊れたい部分だけ ⼊れられた⽅が良い -
Kotlin Multiplatform Project proto Android project apiclient apiclient-fake iOS project
ios-mpp マルチモジュールのさまざまな 利点を受けられる これらはスケールしたときに 影響が出てくる ‧並列でのビルド ‧必要がない依存関係が⼊らない -
Kotlin Multiplatform Project proto Android project apiclient apiclient-fake iOS project
ios-mpp また構成するモジュールが 300を超える Android Jetpackの構成を 参考にしているため、 以下のような仕組みを参考にでき る ‧必要なモジュールだけテストや ビルド : AffectedMoudleDetector ‧必要なモジュールだけIDEに インポート : Android Jetpackの Playgroundについて https:// qiita.com/takahirom/items/ b e c e https://github.com/androidx/androidx/blob/ e d b bf fee b fec fc /buildSrc/src/main/kotlin/androidx/ build/dependencyTracker/AffectedModuleDetector.kt https://github.com/androidx/androidx/blob/ ce d fbed e fbc f /playground-common/README.md -
Kotlin Multiplatform Project proto . . -abd a Android project
apiclient . . apiclient-fake . . iOS project ios-mpp . . Maven implementation(“tv.abema: ”) Maven implementation(“tv.abema:apiclient: . . ”) Maven implementation(“tv.abema:proto: . . -abd a”) 基本的にMavenで管理し(GitHub Packagesを利⽤する)、 バージョンがモジュール毎に存在する 依存モジュールが別のプロジェクトに勝⼿に変更されて、 勝⼿に壊れることがないようにしている。 -
Kotlin Multiplatform Project proto Android project apiclient apiclient-fake iOS project
ios-mpp iOSͰCocoapodsͰϞδϡʔϧΛ·ͱΊͯࢀর͢Δ ৄ͘͠ҎԼʮiOSʹKMMΛಋೖ͢Δtipsʯby 𝚖𝚊𝚛𝚝𝚢-𝚜𝚞𝚣𝚞𝚔𝚒 (@marty_suzuki) https://speakerdeck.com/martysuzuki/iosnikmmwodao-ru-surutips Cocoapods -
プラットフォームで拡張可能にする それぞれのプラットフォームのソースセットでDIする。 ここでは単純にConstractor Injectionしている androidMain/kotlin内 public fun ApiClient( // τοϓϨϕϧؔ
config: ApiClientAndroidConfig, ): ApiClient { return ApiClient(ApiClientAndroidImpl(config), config) } public class ApiClientAndroidConfig( public val okHttpClient: OkHttpClient, loggerEnabled: Boolean, ) : ApiClient.Config( loggerEnabled = loggerEnabled, ) -
expect/actualだとテストが難しい場合がある actualを実装できるのは⼀つだけなので、 テストで置き換えするには以下のように全部openにする必要がある commonMain/ expect open class PlatformExpectActual() { open
fun platform(): String } jvmMain/ actual open class PlatformExpectActual { actual open fun platform(): String = "jvm" } commonTestͷςετ val platform = object : PlatformExpectActual() { override fun platform(): String { return "test platform" } } Client(platform).doIt() -
interfaceとexpect/actualを⽐較する UPQMFWFMؔɺ ม DPNNPO.BJO͔ Βͷݺͼग़͠Ͱ࣮ Ϋϥεͷίϯε τϥΫλΛݺͼग़ ͤΔ͔ ςετͰͷஔ͖ ͑
ڞ௨ॲཧΛॻ͘ FYQFDUBDUVBM ✅ ✅ 🚫 🚫 JOUFSGBDF 🚫 🚫 ✅ ✅ -
Affected Module Detectorを有効化する Affected Module Detectorの仕組み A B C implementation(project(“:B”))
implementation(project(“:C”)) -
Affected Module Detectorを有効化する Affected Module Detectorの仕組み B C isProjectAffected =
true A isProjectAffected = true isProjectAffected = false -
やっていること、やりたいこと • 実際に⼯数を減らす • Kotlin Multiplatformの利⽤範囲の拡⼤ • ICONIXプロセスを⽤いたドメインオブジェ クトやUseCaseの作成、共通化 •
他のデバイスへの展開 • Kotlinの学習⽅法を考える