PLAY DEVELOPERS BLOG

HuluやTVerなどの日本最大級の動画配信を支える株式会社PLAYが運営するテックブログです。

HuluやTVerなどの日本最大級の動画配信を支える株式会社PLAYが運営するテックブログです。

Compose MultiplatformでのAndroid/iOSアプリ開発を試してみた

こんにちは。OTTサービス技術部 開発第3グループの森本です。

この記事では、Compose MultiplatformでのAndroid/iOSアプリの導入についての説明をします。 これからCompose Multiplatformの利用を検討する方の参考になれば幸いです。

Compose Multiplatformとは

Compose Multiplatformは、JetBrainsが開発したKotlin Multiplatformをベースにした宣言的UIフレームワークです。Android向けに開発されたJetpack Composeの技術を利用して、Andoroid、iOS、Webといった複数のプラットフォームでの開発を実現します。

kotlinlang.org

特長

  • 記述はほぼ全てKotlin
    Compose Multiplatformの最大の特長は、すべてのコードをKotlinで記述できます。
  • 宣言的UI
    UI/UX部分はJetpack Composeでの宣言的UIの記述になります。
  • 高いコード共有率
    UIレイヤーを含めて、90%以上のコードを共通化できます。ビジネスロジック、データレイヤー、そしてUI実装まで、大部分のコードをAndroidとiOSで共有することが可能です。
  • ネイティブパフォーマンス
    JavaScriptブリッジを経由せず、各プラットフォームのネイティブコードにコンパイルされるため、ネイティブアプリと同等のパフォーマンスを発揮します。AndroidではJVMバイトコード、iOSではネイティブバイナリとして動作します。
  • 既存プロジェクトへの段階的な導入が可能
    既存のAndroidアプリやiOSアプリに、段階的にCompose Multiplatformを導入できます。すべてを一度に書き換える必要はなく、新機能から徐々に移行することが可能です。

他のクロスプラットフォーム技術との比較

クロスプラットフォーム開発の選択肢として、FlutterやReact Nativeなどがありますが、それぞれの比較した表が以下になります。 Compose Multiplatformは既にAndroidアプリをKotlinで開発している場合や、Kotlinの開発知識がある方にとって導入しやすいクロスプラットフォーム技術と言えます。

項目 Compose Multiplatform Flutter React Native
開発言語 Kotlin Dart JavaScript/TypeScript
UIレンダリング ネイティブ + Skia Skia ネイティブコンポーネント
ネイティブ連携 直接呼び出し可能 Platform Channel経由 Native Modules経由
学習コスト Android開発者には低い Dart言語の学習が必要 Web開発者には低い

導入方法

Compose Multiplatformプロジェクトの導入方法を簡単ですが紹介します。

Step 1: 開発環境の準備

必須ツール:

  • Android Studio(最新版推奨)
  • JDK 11以上
  • Android SDK(API Level 24以上)

iOS開発を行う場合(macOSのみ):

  • Xcode(最新版推奨)
  • Xcode Command Line Tools

Step 2: プロジェクトの作成

Kotlin Multiplatform Wizard(https://kmp.jetbrains.com/)にアクセスし、プロジェクト名とパッケージ名を入力、ターゲットプラットフォームを選択してダウンロードします。または、Android Studioから「Kotlin Multiplatform App」テンプレートを選択して新規プロジェクトを作成することもできます。

Step 3: プロジェクト構造の理解

作成されたプロジェクトは、以下のような構造になっています。

MyKMPApp/
├── composeApp/              # メインアプリケーションモジュール
│   ├── src/
│   │   ├── commonMain/      # 共通コード(Android/iOS共有)
│   │   ├── androidMain/     # Android固有コード
│   │   └── iosMain/         # iOS固有コード
├── iosApp/                  # iOSアプリのエントリーポイント
└── build.gradle.kts         # ルートビルド設定

commonMainには、すべてのプラットフォームで共有されるコードを配置します。UIのエントリーポイント、依存性注入、データレイヤー、UI画面などがここに含まれます。

androidMainiosMainには、それぞれのプラットフォーム固有のコードを配置します。

サンプルプロジェクト

公式が提供するサンプルプロジェクト KMP-App-Template(https://github.com/Kotlin/KMP-App-Template)は、Compose Multiplatformのサンプルとして非常にわかりやすかったので導入したい方は参考にするとよいと思います。 サンプルアプリでは、Metropolitan Museum of Art Collection APIを使用して、美術館のアート作品を一覧表示・詳細表示する機能を持つ実践的なアプリケーションです。

サンプルアプリの特徴:

  • 約95%以上のコードがcommonMainで共有
  • MVVM + Repositoryパターンを採用
  • Koinによる依存性注入
  • Ktorによるネットワーク通信
  • StateFlowを使用したリアクティブな状態管理

このサンプルプロジェクトから、Type-safe Navigation、リアクティブな状態管理、依存性注入、非同期処理、クリーンアーキテクチャなど、多くの実践的なパターンを学ぶことができます。また、ビジネスロジック、データレイヤーからUI実装までほぼ全てのコードが共通部分に記述されており、Compose Multiplatformの良さを感じられるかと思います。

ネイティブ実装が必要となる部分

Compose Multiplatformは多くの機能を共通化できますが、プラットフォーム固有の機能を使用する場合は、ネイティブ実装が必要になります。実際のプロジェクト実装で遭遇した主要な機能を紹介します。

  • 外部アプリ/外部ブラウザの起動
    アプリ内から外部のブラウザやメールアプリなどを起動する機能は、プラットフォームごとに異なるAPIを使用する必要があります。commonMainで共通インターフェースを定義し、androidMainとiosMainでそれぞれ実装するexpect/actualパターンを使用します。 AndroidではIntentを使用し、iOSではUIApplication.sharedApplication.openURLを使用して実装します。
  • フルスクリーン(画面拡大表示)
    動画再生時などにフルスクリーン表示を実現する場合も、プラットフォーム固有の実装が必要です。 Androidでは、API Level 30以降はWindowInsetsController、それ以前はsystemUiVisibilityを使用します。iOSではUIApplication.sharedApplication.setStatusBarHiddenを使用してステータスバーの表示/非表示を制御します。
  • OS情報や端末情報の取得
    プラットフォームごとの処理分岐に使用する端末情報の取得もネイティブ実装が必要です。 AndroidではBuildクラスとPackageManagerを使用し、iOSではUIDeviceNSBundleを使用して、OS名、OSバージョン、デバイスモデル、アプリバージョンなどの情報を取得します。

その他にも、広告ID(ADID/IDFA)の取得、プッシュ通知、カメラ・写真ライブラリアクセス、位置情報取得、バイオメトリクス認証なども、ネイティブ実装が必要な機能として挙げられます。これらの機能は、expect/actualパターンを使用して実装するか、既存のKotlin Multiplatform対応ライブラリを使用することで、共通コードから利用できるようになります。

まとめ

以上、Compose MultiplatformでのAndroid/iOSアプリの導入についての説明でした。 今までやっていた開発がほぼネイティブだったため、AndroidとiOSで別々の開発者のコードを振る舞いを合わせていく必要がありました。 今回、実際に試し開発を行いましたが、共通化部分が多く、開発効率が上がるだけでなく振る舞い差異も少なく開発できそうだったので、ぜひ利用していきたいなと感じました。 もし、Compose Multiplatformの開発に興味のある方の参考になれば幸いです。