Zenn
🚌

Compose Multiplatform で EventBus

2025/03/22に公開

このようなイベント送信に対するアーキテクチャ的な是非は別として。

次のような object を用意しておくと、任意の箇所から送信したイベントを任意の Composable で受け取ることができる。

interface Event // これを継承してイベントを定義する

object EventBus {
    private val _events = MutableSharedFlow<Event>(
        extraBufferCapacity = 10, // tryEmit の採用にあたりバッファ多めに
    )
    val events: Flow<Event> = _events

    // イベントを送信
    fun post(event: Event) {
        _events.tryEmit(event) // suspend なしに post できるよう tryEmit を採用
    }

    // イベントの購読
    @Composable
    inline fun <reified E : Event> subscribe(crossinline block: (event: E) -> Unit) {
        LaunchedEffect(Unit) {
            events.filter { it is E }.collect {
                block.invoke(it as E)
            }
        }
    }
}

Event の送信

// Evnet を定義
data class ShowSnackBar(val message: String) : Event
data object NavigateToBack : Event
// ...

// 任意の箇所で送信。static に呼び出せる
EventBus.post(ShowSnackBar("これはメッセージ"))

Event の購読

@Composable
fun YourScreen() {

    EventBus.subscribe<ShowSnackBar> {
        // do something..
    }

    // ...
}

Discussion

ログインするとコメントできます