conference-app-2021へのコントリビューション記録

コロナ禍で色々と大変だったDroidKaigiですが、明日から開催されます。 例年公式アプリへのコントリビューションをしているので、今年のPRを記録しておこうと思います。

github.com

やってみたもの

SQLDelight

conference-app-2021はKMMを利用していることもあり、DBにSQLDelightが利用されています。

github.com

今回、Jetpack Composeを触ってみたかったのでブロッキングしていたDB作成のIssueに取り掛かりました。 *1

github.com

github.com

SQLDelightを触ったのは今回が初めてだったのですが、たぶんあまり触ったことのある人も多くないのでは? と思います。 Roomに比べるとSQLの知識が求められたり、1:Nな関係を扱うのに工夫が必要でしたが、SQLDelightのInteliJ Pluginなんかを利用するとサクサク書き進めることができました。

plugins.jetbrains.com

.sq ファイルで作成したqueryがそのままメソッド名になるのは、最初は驚きがありますが、使ってみるといいところにいい感じにメソッドが生えてくれるので便利です。 ただ、近いテーブルで同じメソッド名が合った場合にメソッド名がかぶってしまうなど、ちょっとしたワークアラウンドも必要になっていました。 コード生成系は、生成ロジックの気持ちになるのやっぱり大事ですね。

Jetpack Compose

https://github.com/DroidKaigi/conference-app-2021/pull/679tgithub.com

ずーっと触りたかったJetpack Compseによる、セッション詳細画面の実装です。 結果的ではあるのですが、一つ前のDB周りから作っていたためデータクラスの理解や修正がしやすく、非常に楽しんで実装しました。

実装は、普段Flutterを書いていることもあり、Material Designの用語を用いて思考&実装できました。 書いている際にはJetpack Composeが「戻り値のないfunctionで描画するスタイル」であることを意識すると、迷わずに記述できると思います。

at-sushi.work

Flutterとの比較で言うと、下記の点はFlutterより扱いやすいと感じました。

  1. Kotlin + AndroidStudio
  2. 複数のPreview画面
  3. 戻り値がないのでif文やfor文の処理が直感的
  4. Modifier によるViewの調整を共通化

宣言的UIがあると、マルチデバイスへの対応がしやすいと確信しており、次のPRも出してみました。

github.com

宣言的UIを利用する場合、処理が走ったタイミングでViewの制約を取得し処理分岐をすると、Viewのサイズが変わった時に適切に再描画されます。 Jetpack Composeでは BoxWithConstraints を利用することで、Viewの制約をいい感じに取得して実装できます。

developer.android.com

またPreview機能を使うことで、実装中に複数の画面サイズの端末での見え方を抑えながら実装することができます。 今回はスマートフォンとそれ以上で処理を分岐してしまいましたが、より細かな調整をする場合でも when 文に追記をするだけなので、変更に強い状態になります。 今まではxmlを複数作らなければいけなかったので大変でしたが、これからは1つ関数を作るだけ!

Kotlin Serializable

github.com

DB周りをいじっていて、JSONのnullableが伝播しているのが辛いなと思ったので対応しました。 Moshiを使っている場合、Kotlinのdefault valueを追加して不要なnull考慮を避けられるので、同じことがしたかった感じです。

github.com

色々とコードを追ってみると、JSONの時だけ有効になるとか書いてあったりするので、フラグが入る前に採用したプロダクトでも有効にできるのではと思ったりします。 こうしてみると、Kotlin Serializationでできないことがほぼなくなっているので、何を選んでも大丈夫になってきた気がしますね。

Inline Class

github.com

iOSの方もさわってみたいなー」と思っていたところで、ちょっとiOS側にも影響がありそうだったのでやってみました。 UIをざっくり追ってもいまいち感触が掴めなかったので、KMMとSwiftの間をさわれたのでちょうど良かったように思います。

……とは言うものの、こちらの問題はKotlin-Nativeとして未解決の課題が絡んでいます。

github.com

https://youtrack.jetbrains.com/issue/KT-32352youtrack.jetbrains.com


KotlinのInline Class相当のものがSwiftにないので、Swift側でInline ClassがObjective-Cid 型(Swiftの any 型)になってしまいます。 そのことさえカバーできれば、Inline Classの導入は簡単です。

カバー方法はPRで作ったような「Swiftの世界でprimitive型として扱う」方法もあれば、「Swift側で型が呼び出せるよう、KMM側で unwrap メソッドを作って呼び出す」方法もあります。 この辺りは、Issueを監視して最新の推奨をチェックするのが良さそうですね。

まとめ

もうちょっとiOS側のUIとかもいじってみたかったのですが、DroidKaigi前には間に合わず、といったところでした。 残念無念。

毎年感じるのですが、DroidKaigiは発表で最新の情報を学べるのと同時に、アプリで最新の開発を体験できる機会です。 このような場を作ってくださった実行委員会の皆様に感謝しつつ、もう少しPRを出せる場所と時間はないかなと探りながら、DroidKaigi 2021を楽しみたいと思います。

droidkaigi.jp

前回の参加の話。

blog.dr1009.com

*1:Roomで実装しているから簡単だろう、と思っていたらSQLDelightでした