💬

KMPでクラス内の特定の変数のみをプラットフォームごとに置き換えたい

2023/11/18に公開

はじめに

Compose multiplatformを使ってAndroidとDesktopのアプリを作っている際、Ktorを使ってHTTPリクエストがしたくなりました。ただ、Ktorの初期化にはプラットフォームごとにEngineを指定する必要があり、API通信のラッパークラス内に書くことができませんでした。通常の書き方ではクラスの特定の変数のみをexpectにすることは(初期値を入れないと)できなかったので、個人的なメモとして残しておきます。

結論

Kotlinの拡張プロパティを使うことで特定の変数のみをプラットフォームごとに変えることができました。

ApiWrapper
object ApiWrapper {
  private val client by lazy {
      HttpClient(engine) {
        install(ContentNegotiation) {
	  json()
        }
      }
    }
     ...
}

expect val ApiWrapper.engine: HttpClientEngineFactory<HttpClientEngineConfig>
ApiWrapper.android
actual val ApiWrapper.engine: HttpClientEngineFactory<HttpClientEngineConfig>
	get() = Android
ApiWrapper.jvm
actual val ApiWrapper.engine: HttpClientEngineFactory<HttpClientEngineConfig>
	get() = Apache5

まとめ

実のところ、AndroidとDesktopだけに対応するならAndroidEngineを使えば問題なかったりしますし、CIOを使えばIOSにも対応できるのでわざわざこんなことはしなくても大丈夫だと思います。ただ拡張関数、拡張プロパティに対してプラットフォーム固有な実装を楽に使えるのはかなり便利だと思います。

Discussion