🚌
Compose Multiplatform で EventBus
このようなイベント送信に対するアーキテクチャ的な是非は別として。
次のような 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