1
1

Compose Multiplatformを触ってみる

Last updated at Posted at 2024-07-17

image.png

挨拶

初めまして。
bravesoft株式会社でエンジニアリングマネージャーらしき事をしているおじさんです。

以前弊社技術blogにてKMMについての記事を書いていたので、今回はUIも共通化出来るようになった「Compose Multiplatform」について触ってみて所感を書いていこうと思います。

始め方

まずは公式チュートリアルを進めてみる。

image.png

こんな感じ。

まずは環境を整えるから。

image.png

1つずつやっていこうと思うけど、一回斜め読みした結果kdoctorコマンドで必要な環境が整っているのかをチェック出来るようなので、まずこれをやってみる。

> brew install kdoctor
...

> kdoctor
Environment diagnose (to see all details, use -v option):
[✓] Operation System
[✓] Java
[!] Android Studio
  ! Android Studio (AI-222.4459.24.2221.9862592)
    Location: /Applications/Android Studio/Android Studio Flamingo.app
    Bundled Java: openjdk 17.0.6 2023-01-17
    Kotlin Plugin: 222-1.8.0-release-AS3739.54
    Kotlin Multiplatform Mobile Plugin: not installed
    Install Kotlin Multiplatform Mobile plugin - https://plugins.jetbrains.com/plugin/14936-kotlin-multiplatform-mobile
  ! Android Studio (AI-223.8836.35.2231.11005911)
    Location: /Applications/Android Studio/Android Studio Giraffe.app
    Bundled Java: openjdk 17.0.6 2023-01-17
    Kotlin Plugin: 223-1.9.0-release-358-AS8836.35.2231.11005911
    Kotlin Multiplatform Mobile Plugin: not installed
    Install Kotlin Multiplatform Mobile plugin - https://plugins.jetbrains.com/plugin/14936-kotlin-multiplatform-mobile
[✖] Xcode
  ✖ Xcode requires to perform the First Launch tasks
    Launch Xcode and complete setup
[!] CocoaPods
  ! CocoaPods configuration is not required, but highly recommended for full-fledged development
  ✖ System ruby is currently used
    CocoaPods is not compatible with system ruby installation on Apple M1 computers.
    Please install ruby via Homebrew, rvm, rbenv or other tool and make it default
    Detailed information: https://stackoverflow.com/questions/64901180/how-to-run-cocoapods-on-apple-silicon-m1/66556339#66556339
  ✖ CocoaPods requires your terminal to be using UTF-8 encoding.
    Consider adding the following to shell profile
    export LC_ALL=en_US.UTF-8

Conclusion:
  ✖ KDoctor has diagnosed one or more problems while checking your environment.
    Please check the output for problem description and possible solutions.

なんか色々出た。

Android Studioはkotlin-multiplatform-mobileプラグインが入ってないよってことかな。
2つ入っているけどどっちも古いので最新のKoalaも入れた方がいいかも。

Xcodeは入ってるけど一回起動してねって感じ。
そういやインストールしたけど時間切れになって放置してたな・・・

CocoaPodsは必須じゃないけど本格的な開発するなら強く推奨との事だが、今でもCocoaPodsってよく使うのかな? 弊社ではSwift Package Managerを推奨しているけど。

とりあえずCocoaPodsの警告は無視して良さそうなので他についてそれぞれ対処していく。
ここは本筋ではないので特に記載しませんが、最終的に以下のようになっていれば良いはず。

> kdoctor
Environment diagnose (to see all details, use -v option):
[✓] Operation System
[✓] Java
[✓] Android Studio
[✓] Xcode
[!] CocoaPods
  ! CocoaPods configuration is not required, but highly recommended for full-fledged development
  ✖ System ruby is currently used
    CocoaPods is not compatible with system ruby installation on Apple M1 computers.
    Please install ruby via Homebrew, rvm, rbenv or other tool and make it default
    Detailed information: https://stackoverflow.com/questions/64901180/how-to-run-cocoapods-on-apple-silicon-m1/66556339#66556339
  ✖ CocoaPods requires your terminal to be using UTF-8 encoding.
    Consider adding the following to shell profile
    export LC_ALL=en_US.UTF-8

Conclusion:
  ✓ Your operation system is ready for Kotlin Multiplatform Mobile Development!

※ 案件都合で古めのAndroid Studioも残しているけど、キレイに消すには各バージョンでプラグインのインストールが必要でした。
※ CocoaPodsは一旦無視。←色々エラーに見舞われて最終的にはインストールしました。

次のステップに進みます。

image.png

ちょっと気になったのは1つめのKotlin Multiplatform ウィザードってやつ。

ここで設定に応じたプロジェクトテンプレートがダウンロード出来るらしいけど、Android Studioから作った場合とどっちがいいのかな。Android Studioのバージョンが上がったり構成に若干変更があったとしたらこっちも都度メンテされていくのか気になった。
まぁこれも今は本筋ではないので無視するとして、テンプレートギャラリーページを覗いてみる。

image.png

上3つはUIも共通化するパターンとそれぞれのネイティブUIを使うパターン、KMMの最小限テンプレかな?
Amperってなんだろ。一旦無視します。

ひとまずチュートリアルに戻って新規プロジェクトを作ってみる。

image.png

ダウンロードしてzipファイルを解凍後、Android Studio Koalaで開く。

image.png

image.png

image.png

初期状態ではiOSのビルドはまだ出来ないらしい。
iosApp/iosApp.xcodeprojをXcodeで開いて初期セットアップをしろという事で開いてみたところ、iOS Simulatorが1つもないので時間が掛かってしまったが、今回はダウンロードしてみてもiOSの実行構成が出てこなかったため手動で追加をしました。

image.png

この辺りを参考に…

image.png

こんな感じで追加する。

何故かシミュレーターが検知されなかったがビルドしてみるとちゃんと起動した。

image.png

Androidのシミュレーターでもビルドしてみる。

image.png

うん、ちゃんと動きました。

デスクトップとWEBアプリケーションも試してみます。

構成を追加して、

image.png
image.png

image.png
image.png

どちらもちゃんと動きました。

サンプルを動かす

さて、ここから先はチュートリアル通りにやっても面白くないのでサンプルを1つ動かしてみます。
見た目がいい感じだったので以下を使わせていただきました。

とりあえず起動してみる。

image.png

iOSは以下のエラーが出て動かせなかった。

Selected scheme "Pods-Pokedex" has invalid 'PRODUCT_TYPE'

直接 .xcworkspace から起動してみると起動出来ました。 (cocoapodsインストール済み)

image.png

コードを見てみます。

image.png

気になるディレクトリは android ios shared 辺り。(desktopは今回無視します。)

androidディレクトリから見てみます。

image.png

ソースは MainActivity しかなく、リソースファイルも最小限しかない事が分かる。

リソースファイルの中身はこんな感じ。

image.png
image.png

MainActivityを見てみる。

image.png

ざっくりとやっている事はDIを除けばルートコンポーネントを作って ContentView に渡しているだけ。
本体は RootComponentContentView にあるのでしょう。

次は iosディレクトリ を見てみます。

image.png

ここはXcodeプロジェクト置き場らしいですね。
androidディレクトリと対になる名前のディレクトリだけど用途は別っぽいです。
一旦放置します。

sharedディレクトリを見ていきます。

image.png

〜Testは一旦置いておいて、〜Mainを見ていきます。

まずは androidMain から。

image.png

ContentView がありました。

image.png

これは共通化出来なかったのでしょうか。

PokedexDispatchers の中身は以下こんな感じ。

image.png

HttpClientFactory

image.png

AndroidSqlDriverFactory

image.png

特に説明は不要だと思うので次は iosMain を見ていきます。

image.png

大体 androidMain の方にあったファイルですが main.ios.kt ってファイルもあるので見ておきます。

image.png

コードを見ると android ディレクトリの MainActivity と同等のコードになっているようです。
iOSの場合はここにあるんですね。
なんとなく android と合わせたいけどディレクトリ構成は弄れるのかなぁ…

まぁ他のコードも見ていきます。

ContentView

image.png

シンプルですね。
Android の方はテーマを含めたガワの部分もここに入ってましたが、iOS では main.ios.kt に書かれていました。
ただこれは実装上の揺れだと思います。

PokedexDispatchers

image.png

Android側のコードとほぼ同じ内容ですが、以下の部分が違います。

Android

    ...
    override val main: CoroutineDispatcher = Dispatchers.Main.immediate
    override val io: CoroutineDispatcher = Dispatchers.IO
    ...

iOS

    ...
    override val main: CoroutineDispatcher = Dispatchers.Main
    override val io: CoroutineDispatcher = Dispatchers.Default
    ...

Dispatchers.Main.immediateDispatchers.Main
Dispatchers.IODispatchers.Default が違います。

なぜ敢えて分けているのかは分かりませんでした。

HttpClientFactory

image.png

Android と違って Darwin で初期化しています。

SqlDriverFactory

image.png

Android と違って NativeSqliteDriver を返しています。

最後に commonMain を見てみます。

image.png

ここに実際の画面の大部分が収まっています。
殆ど共通化されていて AndroidiOS の違いはごく僅かでした。

image.png

各プラットフォーム別で書かれている ContentView から呼び出されている RootContent がこちら。
Jetpack Composeで書かれていて、これに慣れている人はサクサク書いていける予感はあります。

大体分かってきたので今回はここまでとしてまとめに入ります。

個人的な所感

弊社ではあまり積極的にマルチプラットフォーム開発を採用していないのですが、もしこれから採用するとしたらやっぱりFlutterかなぁと思いました。
既にいくつか実績もありますし、Flutterも成熟してきてライブラリ含めたエコシステムも充実していて、開発体験をみてもホットリロードの有無は大きいです。

またCompose Multiplatformの方は今回触っている中でなかなか期待通りに動かない部分が結構ありました。
まっさらなMacで環境を作っていった時と違い、既にJavaやAndroid Studioがいくつか入っている中で環境構築していく過程で躓いたり、サンプルがスムーズに動かなかったりと環境で躓く事が多い印象です。

この辺りは普段からAndroidアプリをバリバリ開発しているエンジニアであればまた違う感想を抱くかもしれないので是非試してみて欲しいなと思います。

もっとこういう点がFlutterよりも優れているよ、というご意見があればコメントいただけると参考に致します。


bravesoftではiOSアプリやAndroidアプリの開発を行っています。 アプリ開発に興味がある方は是非、採用ページをご確認ください。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1