この本を手に取っていただき、どうもありがとうございます。著者のFORTE(フォルテ)です。今回は、Compose Multiplatformでデスクトップアプリを開発する流れを紹介する技術同人誌になります。今までKotlinに関する技術同人誌はサーバーサイドKotlinについて書いてきましたが、ネタ切れしたのでしばらくお休みしていました。その結果、Compose Multiplatformが面白そう、スマホ向けの記事はあるけどデスクトップアプリ向けは少ない(個人的にスマホはネイティブの方が好き)、ということでCompose Multiplatformでデスクトップアプリを作成する内容となりました。そのため、サーバーサイドKotlinシリーズではないですが、Kotlinシリーズとしては5冊目の技術同人誌となります。
本著もこれまでのサーバーサイドKotlinシリーズ同様、Windows、Mac両対応です。今まではIntelliJ IDEA、VS Codeの両IDEに対応してきましたが、今回はVS Codeは付録となります。というのも、Compose Multiplatformを始めるのにIntelliJ IDEAの方が圧倒的に簡単、かつ、楽でVS Codeだと、ただただ面倒臭い手順が必要になるためです。そのため、本著ではできあがったソースをVS Codeで動かす手順は紹介しますが、VS Codeでの開発はおすすめしません。今後、プラグインなどで状況が変わることはあると思うので、VS Code派の方はアンテナを立てておくといいでしょう。
本著はCompose Multiplatformでの開発について、主に次の内容を紹介しています。
・Compose Multiplatformの紹介と関連技術について
・Compose Multiplatformプロジェクトの作成と実行方法
・主なUIコンポーネントの実装方法
・ウィンドウ管理の実装方法
・簡単なデスクトップアプリ開発の例としてデジタル時計アプリの開発を紹介
・Windows、Mac用それぞれの実行ファイル作成方法
そもそもCompose Multiplatformとはなんなのか?どういったことに使えるのか?似たようなライブラリーとの差異についても解説します。
ほとんど公式のGithubリポジトリーで紹介されている内容ではありますが、実際にやってみた記録として、またやってみて得られた注意点などを紹介します。
Compose Multiplatformでは、Jetpack Composeを利用してUIコンポーネントを実装できます。いくつかのコンポーネントを実装してみて、実際にデスクトップアプリとして表示してみましょう。
デスクトップアプリは通常一枚のウィンドウとして表示されます。このウィンドウ管理の基本について紹介します。
ここまで紹介した内容のまとめとして、簡単なデスクトップアプリの実装例を紹介します。アプリの内容はデジタル時計です。個人的な話ですが、デスクトップの前面に常に時計が表示されていると便利だと感じています。WindowsもMacもタスクバーやメニューバーに時計は表示できますが、どちらも非表示にしていると、カーソルを動かさないと表示できません。かといって、時計のためにそれらを常に表示しているとウィンドウの表示領域が常に少なくなってしまいますし、時計以外の余計な情報も表示されてしまいます。常に前面に時刻だけ表示されていてほしいという要望を満たすには、デスクトップアプリが一番と考えています。
なお、Macでは今後のOSアップデートでデスクトップにウィジェットとして時計を設置可能になる予定だそうですが、デジタル表記が可能かは不明ですし、移動可能にしたい、常に前面表示したい、邪魔なときは一時的に最小化したいなどの細かな制御が可能かはわかりません。Windowsでも11でウィジェット機能が追加されましたが、デジタル時計が存在するかはわかりませんでした、著者はまだWindows10なので実際に確認もできず、少しググった程度ではデジタル時計を表示する方法は見つかりませんでした。また、仮にウィジェットで追加可能であったとしても、Mac同様に細かい制御が可能かは不明です。そのため、自分好みに設定できるようにデスクトップアプリで開発してみました。
最後に単一のアプリケーションとしてWindows、Macの両OSで実行可能なファイル形式に変換する方法を紹介します。これはGradleの機能を使って実現できます。対象のファイル形式はWindowsは.msi、Macは.dmg形式です。
本著は、次のような方を対象として執筆しました。
・Kotlinに興味があり、Kotlinで何か書いてみたい
・デスクトップアプリを作ってみたい
・Windows・Macどちらでも動くアプリを作りたい
・Compose Multiplatformが気になっていた
前提知識は必要ないように書いていますが、Kotlinとは?みたいな基本的なことは解説していないので、KotlinやGradleについて基礎から学びたい方は拙著「入門!実践!サーバーサイドKotlin」をご覧ください、Kotlin初心者向けに1から丁寧に解説しています。電子版は次のリンクかQRコードから、紙版はAmazonで購入できます。
この本を読むことで、次のことが得られます。
・Compose Multiplatformが何かわかる
・Compose Multiplatformの開発環境が作成できる
・Jetpack Composeについて学べる
・Windows・Macどちらでも動くアプリをひとつのコードで作成できるようになる
Compose MultiplatformではJetpack Composeを使用していますが、Jetpack Composeについて詳細には解説しません。あくまで利用方法のみ、コードで解説する形になります。
また、前述したとおり、KotlinやGradleについて詳細な解説はしません。
本文中の内容で不明点があればX(旧Twitter)「https://twitter.com/FORTEgp05」か、奥付に記載したメールアドレスまでご連絡ください。ベストエフォートでご回答いたします。
基本的に先頭から読み進めていけばいいですが、気になったところだけ摘んでいく形でも問題ありません。特に既にCompose Multiplatformを使用している方は、アプリ開発例の部分だけを読んでもいいかもしれません。
本書に記載する内容は、筆者の所属する組織の公式見解ではありません。また、本書は可能な限り正確を期すように努めていますが、筆者がその内容を保証するものではありません。そのため、本書の記載内容に基づいた読者の行為、及び読者が被った損害について筆者はなんら責任を負うものではありません。
本書に記載されている会社名、製品名などは、一般に各社の登録商標または商標、商品名です。会社名、製品名については、本文中では©、®、™マークなどは表示していません。
Compose Multiplatformは、KotlinとJetpack Composeを使用した複数のプラットフォーム間でユーザーインターフェース(UI)を共有できる宣言的フレームワークです。サポートしているレベルに差はありますが、執筆時点(2024年2月)で次のプラットフォームでの開発に対応しています。
・iOS(α版)
・Android
・Windows
・Mac
・Linux
・Web(α以前の実験的なバージョン)
Compose Multiplatformを使えば、異なるプラットフォーム間でも同じコードでラベルやボタンなどが実装できます。これにより複数のコードベースを管理する必要がなくなったり、それぞれ専門のスキルをもったプログラマーじゃなくても、KotlinとJetpack Composeを扱える人材なら誰でも、前述のプラットフォームでアプリのUI開発ができます。これはAndroid開発の経験を他のプラットフォームの開発に活かせますし、これから学ぶ人はCompose Multiplatformだけ学べば、複数のプラットフォームでUI開発ができるようになります。
UIを共有するのが目的のフレームワークなので、ビジネスロジックの共通化は行えません。異なるプラットフォーム間でKotlinを用いてロジックを共通化する仕組みは別途提供されており、Kotlin Multiplatform(KMP)がそれにあたります。
冒頭に説明したとおり、Compose MultiplatformはKotlinとJetpack Composeを使用しています。ここで、このふたつの技術から得られる主要なメリットを紹介します。
・Kotlinから得られる三つの大きなメリット
─コード記述量が減る
─null安全
─Javaの資産が使える
・Jetpack Composeから得られるふたつの大きなメリット
─宣言的なUI構築が可能
─モダンなアニメーション
ひとつずつ見ていきましょう。
KotlinはJavaに比べシンプルで書きやすいのが特徴となっており、ロジックにもよりますがJavaより2〜3割記述量を減らすことが可能です。具体的な比較を行うコードは記載しませんが、過去にGithubのAPIを実行してリポジトリ一覧を取得する処理をJavaとKotlinで書いた際、KotlinはJavaの8割程度の文字数で済んだ経験があります。コード量が少ないということは生産性が上がり、メンテナンス性も上がり、実装者の疲労度も下がるため、メリットしかありません。
Kotlinは元となったJavaに比べて、nullに対する安全性が飛躍的に高まりました。変数宣言時デフォルトでnullの代入が非許可であり、nullを許容する場合は?で明示する必要があるため、コーディング中にnullが代入される可能性がある場合は警告され実行前に気づけ未然にバグを回避できますし、可読性が向上します。また、オブジェクトのプロパティーや関数にアクセスする際により、安全に簡単に呼び出せる仕組みが存在しています。これによりnullの可能性があるオブジェクトに対するアクセスが、Javaに比べて簡潔に記述できるようになりました。
Kotlinは、Java製のライブラリーを使用することができます。そのため、長いJavaの歴史で積み上げられた資産を利用することができます。実際、拙著「いろいろ実践!サーバーサイドKotlin Vol.2」では、twitter4jというJava製ライブラリーをサーバーサイドKotlinで使用する例を紹介しています。この特性を活かしてJavaプロジェクトの一部分からKotlinに置き換えていくことが可能です。
宣言的UIとは、UIを表示される状態で宣言(定義)することを指します。従来のUI定義(宣言的ではないUI定義)はUIを宣言的UIに比べて複雑なロジックや場合によっては別言語で記述していたため、次のような点で不便な点がありました。
・ロジックを追わないと何のUIかわからない
・UI定義が別ファイルに分かれてしまう(言語も異なる)場合がある
・テストコードを書くのが難しい
宣言的UIではこれらが解決され、ロジックは不要で宣言的な記述のみでUIを表現でき、ロジックが不要になったことによりテストコードが書きやすくなっています。長くなるため実際のコードは記述しませんが、Jetpack Composeを用いたAndroidの宣言的UIではUI定義をKotlinで記述することができますし、それも関数化することができるので、テストも簡単にできます。対して、従来の記述の仕方ではXMLにUI定義を記述していたので、ロジックとUIが分かれてしまっており、テストも難しいものでした。宣言的UIに比べて可読性に劣り、メンテナンス性も劣っていました。
宣言的UIについてメリットをまとめると、上記の逆の効果が得られるということになります。次にまとめてみましょう。
・直感的な表現でUIを定義できる(可読性の向上)
・同じ言語、ファイルでUIを定義できる
・ロジックと同じ言語で書かれ、関数化もできるのでテストしやすい
宣言的UIにはこのようなメリットがあります。
Jetpack Composeには、UIをアニメーションさせるためのAPI(仕組み)が提供されています。これらのアニメーションは宣言的UIと同様に宣言的に記述でき、可読性の高い記述が可能です。また、テスト用の機能も提供されており、メンテナンス性も高いのが特徴です。Jetpack Composeでは、UIのサイズ指定にアニメーション用の関数を指定すればいいのに対し、従来のコードではアニメーションさせたいときにクリックなどのイベントハンドラー内部にロジックを書く必要があり、コードが冗長になってしまいます。Jetpack Composeを使用すれば、モダンなアニメーションを簡単に、わかりやすい実装で利用することができます。
既に記載した通り、Compose Multiplatformは異なるプラットフォーム間でUIを共有できるフレームワークであり、ロジックの共有にはKotlin Multiplatform(KMP)が用いられます。ここでは、簡単にKMPについて紹介します。なお、過去にはKotlin Multiplatform Mobile(KMM)という呼称もありましたが、これは非推奨となりました。詳しくは、公式のブログの該当記事(https://blog.jetbrains.com/kotlin/2023/07/update-on-the-name-of-kotlin-multiplatform/)をご参照ください。簡単に説明すると、当初はモバイルの異なるプラットフォーム(iOSとAndroid)をKotlinで開発できる点を推したため、KMMという名前で発表されましたが、既にKMPはモバイルだけでなく、デスクトップやWebまでもが対応範囲に入っています。そのため、モバイルだけと誤解を受けやすいKMMを廃止し、KMPに統一する運びとなりました。
KMPは、異なるプラットフォームでロジックを共有できる技術を指します。ここでいうロジックとはネットワーク処理やデータバリデーション、データ検証、分析、計算など一般的にビジネスロジックと呼ばれるものです。KMPがサポートするプラットフォームは次の通りです。
・Server
・Android
・iOS
・Desktop(Windows、Mac、Linux)
・Web
Serverを含む全てのプラットフォームを対象にした場合、Common Multiplatformと呼び、Server以外を対象にした場合、Client Multiplatformと呼ばれます。ここでいうServerとは主にWebサーバーのことであり、サーバーサイドKotlinのことを指します。執筆時点ではKtorがKMPに対応しています。KMPに対応している他のライブラリーとしては、GraphQLクライアントのApollo、Kotlinで関数型プログラミングを可能にするArrow、データベースアクセス用ライブラリーであるSQLDelight、組み込み型のデータベースであるRealmなどがあります。本著ではKMPについて詳細は説明しませんが、興味がある形はKotlinの公式ドキュメントにチュートリアルがあるので、手を動かしてみるといいでしょう。チュートリアルのURLはhttps://kotlinlang.org/docs/multiplatform-library.htmlとなります。