Compose MultiplatformでブラウザにてURLを開く方法

Compose MultiplatformではURLをブラウザで開くのにAndroid・iOS毎に処理を記述する必要がありそうと感じるのだが、そんなことはなくてUriHandlerで実装される共通の処理でURLをブラウザで開くことができます。本記事ではUriHandlerの使い方を簡単に説明していきます。

目次

UriHandlerとは?

UriHandlerは以下の定義のインタフェースで、ブラウザで特定のURLを開くためのopenUriだけが定義されています。

Kotlin
/**
 * An interface of providing platform specific URL handling.
 */
interface UriHandler {
    /**
     * Open given URL in browser
     */
    fun openUri(uri: String)
}

LocalUriHandlerでUriHandlerは取得できる

UriHandlerはLocalCompositionに登録されているため、LocalUriHandlerのcurrentから以下のように取得できるようになっています。

Kotlin
val urlHandler = LocalUriHandler.current

取得したUriHandlerでブラウザで特定のURLを開く

LocalriHandlerのcurrentから取得したUriHandlerを利用した、以下のデモを利用してブラウザで特定のURLを開いてみる。

Kotlin
@Composable
internal fun App() {
    MaterialTheme {
        Box(
            modifier = Modifier
                .fillMaxSize()
                .windowInsetsPadding(WindowInsets.safeDrawing)
        ) {
            Column(
                verticalArrangement = Arrangement.spacedBy(16.dp),
                modifier = Modifier.align(Alignment.Center)
            ) {
                val urlHandler = LocalUriHandler.current
                var url by remember { mutableStateOf("https://example.com") }
                TextField(value = url, onValueChange = { url = it })
                Button(
                    onClick = {
                        try {
                            urlHandler.openUri(url)
                        } catch (e: Exception) {
                            println(e)
                        }
                    },
                    modifier = Modifier.align(Alignment.CenterHorizontally)
                ) {
                    Text("Open")
                }
            }
        }
    }
}

以下のようにAndroid・iOSの両方で問題なく、画面遷移してブラウザで特定のURLが開ける

おわりに

Compose MultiplatformのサンプルなどにURLを開く処理を各OSで記述しているため、このようなURLを開く処理を自作しなければならないと勘違いしそうなのですが、このようにLocalUriHandlerが用意されているのでブラウザで開くだけなら簡単にできます。Compose MultiplatformではこのようなTipsが公式ドキュメントに記載されていないのが辛いところではあるのですが、SlackやIssuesなどをチェックして粘り強く情報収集しましょう。