core
A lightweight multiplatform library providing the fundamental concepts and interfaces for handling navigation results in applications.
Overview
The Core module of Boomerang contains the essential components that power both the Compose and Fragment modules. It defines the key interfaces and classes for storing, retrieving, and processing navigation results between screens without tight coupling between components.
This module supports Android, iOS, and Desktop platforms, providing a consistent API across all platforms while using platform-specific implementations under the hood.
Installation
Add the following dependency to your app's build.gradle.kts
file:
// For core functionality (required by all Boomerang modules)
implementation("io.github.buszi.boomerang:core:1.4.0")
The Core module is required by both the Compose and Fragment modules, so you'll need to include it regardless of which integration you're using.
Key Components
BoomerangStore
The BoomerangStore
interface defines a key-value store for navigation results:
interface BoomerangStore {
fun getValue(key: String): Boomerang?
fun storeValue(key: String, value: Boomerang)
fun storeEvent(key: String)
fun dropValue(key: String)
fun tryConsumeValue(key: String, catcher: BoomerangCatcher)
fun packState(): Boomerang
fun restoreState(boomerang: Boomerang)
}
This interface provides methods for:
Retrieving a value for a key (
getValue
)Storing a value with a key (
storeValue
)Storing an event notification with a key (
storeEvent
)Removing a value for a key (
dropValue
)Trying to catch a value using a
BoomerangCatcher
(tryConsumeValue
)Packing the store's state into a Boomerang object (
packState
)Restoring the store's state from a Boomerang object (
restoreState
)
BoomerangCatcher
The BoomerangCatcher
functional interface is used for catching and processing Boomerang values:
fun interface BoomerangCatcher {
fun tryCatch(value: Boomerang): Boolean
}
Implementations of this interface determine whether a Boomerang value should be "caught" (processed and removed from the store).
EventBoomerangCatcher
The eventBoomerangCatcher
function creates a specialized BoomerangCatcher
for handling event notifications:
inline fun eventBoomerangCatcher(
key: String,
crossinline onEvent: () -> Unit,
): BoomerangCatcher
This function is useful when you only need to be notified that something happened, without needing to pass any additional data. It checks if the Boomerang contains an event with the specified key and calls the provided callback when the event is caught.
DefaultBoomerangStore
The DefaultBoomerangStore
class is the default implementation of the BoomerangStore
interface:
class DefaultBoomerangStore : BoomerangStore {
// Implementation of BoomerangStore methods
}
The DefaultBoomerangStore
uses a private mutable map to store key-value pairs and provides methods for packing and restoring its state. It's designed to work across all supported platforms (Android, iOS, Desktop).
BoomerangStoreHost
The BoomerangStoreHost
interface is for components that host a BoomerangStore
:
interface BoomerangStoreHost {
var boomerangStore: BoomerangStore?
}
This interface is typically implemented by Activities or other lifecycle-aware components that need to provide a BoomerangStore
to their children.
Logging Components
Boomerang provides optional logging capabilities to help with debugging:
BoomerangLogger
The BoomerangLogger
interface defines a simple logging mechanism:
interface BoomerangLogger {
fun log(tag: String, message: String)
}
This interface can be implemented by applications to integrate with their preferred logging system.
BoomerangConfig
The BoomerangConfig
object provides global configuration options:
object BoomerangConfig {
var logger: BoomerangLogger? = null
}
By default, logger
is null
, which means logging is disabled. To enable logging, set this property to an instance of BoomerangLogger
.
AndroidBoomerangLogger
For Android applications, Boomerang provides an Android-specific logger that integrates with Android's Log utility:
class AndroidBoomerangLogger(
private val level: LogLevel = LogLevel.DEBUG
) : BoomerangLogger
The LogLevel
enum defines the available log levels (VERBOSE, DEBUG, INFO, WARN, ERROR).
Usage
The Core module is not typically used directly in your application code. Instead, you'll use either the Compose or Fragment modules, which provide integration with their respective UI frameworks.
However, if you're building a custom integration or need direct access to the core functionality, you can use the Core module as follows:
Creating a Store
// Create a new DefaultBoomerangStore
val store = DefaultBoomerangStore()
Storing a Value
// Store the result with a key using the builder pattern
store.storeValue("home_screen_result") {
putString("selectedItem", "Item 1")
putInt("quantity", 5)
}
Retrieving a Value
// Get a value for a key
val boomerang = store.getValue("home_screen_result")
// Extract data from the boomerang
val selectedItem = boomerang?.getString("selectedItem")
val quantity = boomerang?.getInt("quantity")
Catching a Value
// Try to catch a value using a BoomerangCatcher
store.tryConsumeValue("home_screen_result") { boomerang ->
// Process the boomerang
val selectedItem = boomerang.getString("selectedItem")
val quantity = boomerang.getInt("quantity")
// Return true to indicate the value was successfully caught and should be removed
true
}
Storing and Catching Events
// Store an event notification
store.storeEvent("notification_event")
// Create an event catcher
val eventCatcher = eventBoomerangCatcher("notification_event") {
// This callback is executed when the event is caught
println("Event received!")
}
// Try to catch the event
store.tryConsumeValue("notification_event", eventCatcher)
Saving and Restoring State
// Pack the store's state into a Boomerang object
val stateBoomerang = store.packState()
// Later, restore the store from the saved state
val restoredStore = DefaultBoomerangStore().apply {
restoreState(stateBoomerang)
}
Configuring Logging
// For Android applications
BoomerangConfig.logger = AndroidBoomerangLogger(LogLevel.DEBUG)
// For other platforms or simple console logging
BoomerangConfig.logger = BoomerangLogger.PRINT_LOGGER
// Create a custom logger
val customLogger = object : BoomerangLogger {
override fun log(tag: String, message: String) {
// Integrate with your preferred logging system
YourLoggingSystem.log("$tag: $message")
}
}
BoomerangConfig.logger = customLogger
// Disable logging
BoomerangConfig.logger = null
When logging is enabled, Boomerang will log operations like storing and retrieving values, which can be helpful for debugging navigation flows and understanding how data is being passed between screens.
Advanced Usage
Custom BoomerangStore Implementation
You can create your own implementation of the BoomerangStore
interface if you need custom behavior:
class MyCustomBoomerangStore : BoomerangStore {
// Custom implementation of BoomerangStore methods
}
Custom BoomerangCatcher Implementation
You can create a reusable BoomerangCatcher
implementation:
val myCatcher = BoomerangCatcher { bundle: Bundle ->
// Process the bundle
true // Return true to indicate the value was successfully caught
}
// Use the catcher
store.tryCatch("some_key", myCatcher)
Platform-Specific Implementations
The Core module provides platform-specific implementations of the Boomerang
interface:
Android
On Android, the AndroidBoomerang
class implements the Boomerang
interface using Android's Bundle for storage. This provides efficient integration with Android's saved instance state mechanism.
iOS and Desktop
On iOS and Desktop, the MapBoomerang
class implements the Boomerang
interface using a MutableMap for storage. This provides a lightweight and efficient storage mechanism for these platforms.
The BoomerangFactory
object provides a platform-specific factory for creating the appropriate Boomerang
implementation for the current platform.
Requirements
Kotlin 1.5.0+
Platform-specific requirements:
Android: API level 21+
iOS: iOS 14+
Desktop: JVM 11+
License
Copyright 2025 Buszi
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
A lightweight multiplatform library providing the fundamental concepts and interfaces for handling navigation results in applications.
Overview
The Core module of Boomerang contains the essential components that power both the Compose and Fragment modules. It defines the key interfaces and classes for storing, retrieving, and processing navigation results between screens without tight coupling between components.
This module supports Android, iOS, and Desktop platforms, providing a consistent API across all platforms while using platform-specific implementations under the hood.
Installation
Add the following dependency to your app's build.gradle.kts
file:
// For core functionality (required by all Boomerang modules)
implementation("io.github.buszi.boomerang:core:1.4.0")
The Core module is required by both the Compose and Fragment modules, so you'll need to include it regardless of which integration you're using.
Key Components
BoomerangStore
The BoomerangStore
interface defines a key-value store for navigation results:
interface BoomerangStore {
fun getValue(key: String): Boomerang?
fun storeValue(key: String, value: Boomerang)
fun storeEvent(key: String)
fun dropValue(key: String)
fun tryConsumeValue(key: String, catcher: BoomerangCatcher)
fun packState(): Boomerang
fun restoreState(boomerang: Boomerang)
}
This interface provides methods for:
Retrieving a value for a key (
getValue
)Storing a value with a key (
storeValue
)Storing an event notification with a key (
storeEvent
)Removing a value for a key (
dropValue
)Trying to catch a value using a
BoomerangCatcher
(tryConsumeValue
)Packing the store's state into a Boomerang object (
packState
)Restoring the store's state from a Boomerang object (
restoreState
)
BoomerangCatcher
The BoomerangCatcher
functional interface is used for catching and processing Boomerang values:
fun interface BoomerangCatcher {
fun tryCatch(value: Boomerang): Boolean
}
Implementations of this interface determine whether a Boomerang value should be "caught" (processed and removed from the store).
EventBoomerangCatcher
The eventBoomerangCatcher
function creates a specialized BoomerangCatcher
for handling event notifications:
inline fun eventBoomerangCatcher(
key: String,
crossinline onEvent: () -> Unit,
): BoomerangCatcher
This function is useful when you only need to be notified that something happened, without needing to pass any additional data. It checks if the Boomerang contains an event with the specified key and calls the provided callback when the event is caught.
DefaultBoomerangStore
The DefaultBoomerangStore
class is the default implementation of the BoomerangStore
interface:
class DefaultBoomerangStore : BoomerangStore {
// Implementation of BoomerangStore methods
}
The DefaultBoomerangStore
uses a private mutable map to store key-value pairs and provides methods for packing and restoring its state. It's designed to work across all supported platforms (Android, iOS, Desktop).
BoomerangStoreHost
The BoomerangStoreHost
interface is for components that host a BoomerangStore
:
interface BoomerangStoreHost {
var boomerangStore: BoomerangStore?
}
This interface is typically implemented by Activities or other lifecycle-aware components that need to provide a BoomerangStore
to their children.
Logging Components
Boomerang provides optional logging capabilities to help with debugging:
BoomerangLogger
The BoomerangLogger
interface defines a simple logging mechanism:
interface BoomerangLogger {
fun log(tag: String, message: String)
}
This interface can be implemented by applications to integrate with their preferred logging system.
BoomerangConfig
The BoomerangConfig
object provides global configuration options:
object BoomerangConfig {
var logger: BoomerangLogger? = null
}
By default, logger
is null
, which means logging is disabled. To enable logging, set this property to an instance of BoomerangLogger
.
AndroidBoomerangLogger
For Android applications, Boomerang provides an Android-specific logger that integrates with Android's Log utility:
class AndroidBoomerangLogger(
private val level: LogLevel = LogLevel.DEBUG
) : BoomerangLogger
The LogLevel
enum defines the available log levels (VERBOSE, DEBUG, INFO, WARN, ERROR).
Usage
The Core module is not typically used directly in your application code. Instead, you'll use either the Compose or Fragment modules, which provide integration with their respective UI frameworks.
However, if you're building a custom integration or need direct access to the core functionality, you can use the Core module as follows:
Creating a Store
// Create a new DefaultBoomerangStore
val store = DefaultBoomerangStore()
Storing a Value
// Store the result with a key using the builder pattern
store.storeValue("home_screen_result") {
putString("selectedItem", "Item 1")
putInt("quantity", 5)
}
Retrieving a Value
// Get a value for a key
val boomerang = store.getValue("home_screen_result")
// Extract data from the boomerang
val selectedItem = boomerang?.getString("selectedItem")
val quantity = boomerang?.getInt("quantity")
Catching a Value
// Try to catch a value using a BoomerangCatcher
store.tryConsumeValue("home_screen_result") { boomerang ->
// Process the boomerang
val selectedItem = boomerang.getString("selectedItem")
val quantity = boomerang.getInt("quantity")
// Return true to indicate the value was successfully caught and should be removed
true
}
Storing and Catching Events
// Store an event notification
store.storeEvent("notification_event")
// Create an event catcher
val eventCatcher = eventBoomerangCatcher("notification_event") {
// This callback is executed when the event is caught
println("Event received!")
}
// Try to catch the event
store.tryConsumeValue("notification_event", eventCatcher)
Saving and Restoring State
// Pack the store's state into a Boomerang object
val stateBoomerang = store.packState()
// Later, restore the store from the saved state
val restoredStore = DefaultBoomerangStore().apply {
restoreState(stateBoomerang)
}
Configuring Logging
// For Android applications
BoomerangConfig.logger = AndroidBoomerangLogger(LogLevel.DEBUG)
// For other platforms or simple console logging
BoomerangConfig.logger = BoomerangLogger.PRINT_LOGGER
// Create a custom logger
val customLogger = object : BoomerangLogger {
override fun log(tag: String, message: String) {
// Integrate with your preferred logging system
YourLoggingSystem.log("$tag: $message")
}
}
BoomerangConfig.logger = customLogger
// Disable logging
BoomerangConfig.logger = null
When logging is enabled, Boomerang will log operations like storing and retrieving values, which can be helpful for debugging navigation flows and understanding how data is being passed between screens.
Advanced Usage
Custom BoomerangStore Implementation
You can create your own implementation of the BoomerangStore
interface if you need custom behavior:
class MyCustomBoomerangStore : BoomerangStore {
// Custom implementation of BoomerangStore methods
}
Custom BoomerangCatcher Implementation
You can create a reusable BoomerangCatcher
implementation:
val myCatcher = BoomerangCatcher { bundle: Bundle ->
// Process the bundle
true // Return true to indicate the value was successfully caught
}
// Use the catcher
store.tryCatch("some_key", myCatcher)
Platform-Specific Implementations
The Core module provides platform-specific implementations of the Boomerang
interface:
Android
On Android, the AndroidBoomerang
class implements the Boomerang
interface using Android's Bundle for storage. This provides efficient integration with Android's saved instance state mechanism.
iOS and Desktop
On iOS and Desktop, the MapBoomerang
class implements the Boomerang
interface using a MutableMap for storage. This provides a lightweight and efficient storage mechanism for these platforms.
The BoomerangFactory
object provides a platform-specific factory for creating the appropriate Boomerang
implementation for the current platform.
Requirements
Kotlin 1.5.0+
Platform-specific requirements:
Android: API level 21+
iOS: iOS 14+
Desktop: JVM 11+
License
Copyright 2025 Buszi
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
A lightweight multiplatform library providing the fundamental concepts and interfaces for handling navigation results in applications.
Overview
The Core module of Boomerang contains the essential components that power both the Compose and Fragment modules. It defines the key interfaces and classes for storing, retrieving, and processing navigation results between screens without tight coupling between components.
This module supports Android, iOS, and Desktop platforms, providing a consistent API across all platforms while using platform-specific implementations under the hood.
Installation
Add the following dependency to your app's build.gradle.kts
file:
// For core functionality (required by all Boomerang modules)
implementation("io.github.buszi.boomerang:core:1.4.0")
The Core module is required by both the Compose and Fragment modules, so you'll need to include it regardless of which integration you're using.
Key Components
BoomerangStore
The BoomerangStore
interface defines a key-value store for navigation results:
interface BoomerangStore {
fun getValue(key: String): Boomerang?
fun storeValue(key: String, value: Boomerang)
fun storeEvent(key: String)
fun dropValue(key: String)
fun tryConsumeValue(key: String, catcher: BoomerangCatcher)
fun packState(): Boomerang
fun restoreState(boomerang: Boomerang)
}
This interface provides methods for:
Retrieving a value for a key (
getValue
)Storing a value with a key (
storeValue
)Storing an event notification with a key (
storeEvent
)Removing a value for a key (
dropValue
)Trying to catch a value using a
BoomerangCatcher
(tryConsumeValue
)Packing the store's state into a Boomerang object (
packState
)Restoring the store's state from a Boomerang object (
restoreState
)
BoomerangCatcher
The BoomerangCatcher
functional interface is used for catching and processing Boomerang values:
fun interface BoomerangCatcher {
fun tryCatch(value: Boomerang): Boolean
}
Implementations of this interface determine whether a Boomerang value should be "caught" (processed and removed from the store).
EventBoomerangCatcher
The eventBoomerangCatcher
function creates a specialized BoomerangCatcher
for handling event notifications:
inline fun eventBoomerangCatcher(
key: String,
crossinline onEvent: () -> Unit,
): BoomerangCatcher
This function is useful when you only need to be notified that something happened, without needing to pass any additional data. It checks if the Boomerang contains an event with the specified key and calls the provided callback when the event is caught.
DefaultBoomerangStore
The DefaultBoomerangStore
class is the default implementation of the BoomerangStore
interface:
class DefaultBoomerangStore : BoomerangStore {
// Implementation of BoomerangStore methods
}
The DefaultBoomerangStore
uses a private mutable map to store key-value pairs and provides methods for packing and restoring its state. It's designed to work across all supported platforms (Android, iOS, Desktop).
BoomerangStoreHost
The BoomerangStoreHost
interface is for components that host a BoomerangStore
:
interface BoomerangStoreHost {
var boomerangStore: BoomerangStore?
}
This interface is typically implemented by Activities or other lifecycle-aware components that need to provide a BoomerangStore
to their children.
Logging Components
Boomerang provides optional logging capabilities to help with debugging:
BoomerangLogger
The BoomerangLogger
interface defines a simple logging mechanism:
interface BoomerangLogger {
fun log(tag: String, message: String)
}
This interface can be implemented by applications to integrate with their preferred logging system.
BoomerangConfig
The BoomerangConfig
object provides global configuration options:
object BoomerangConfig {
var logger: BoomerangLogger? = null
}
By default, logger
is null
, which means logging is disabled. To enable logging, set this property to an instance of BoomerangLogger
.
AndroidBoomerangLogger
For Android applications, Boomerang provides an Android-specific logger that integrates with Android's Log utility:
class AndroidBoomerangLogger(
private val level: LogLevel = LogLevel.DEBUG
) : BoomerangLogger
The LogLevel
enum defines the available log levels (VERBOSE, DEBUG, INFO, WARN, ERROR).
Usage
The Core module is not typically used directly in your application code. Instead, you'll use either the Compose or Fragment modules, which provide integration with their respective UI frameworks.
However, if you're building a custom integration or need direct access to the core functionality, you can use the Core module as follows:
Creating a Store
// Create a new DefaultBoomerangStore
val store = DefaultBoomerangStore()
Storing a Value
// Store the result with a key using the builder pattern
store.storeValue("home_screen_result") {
putString("selectedItem", "Item 1")
putInt("quantity", 5)
}
Retrieving a Value
// Get a value for a key
val boomerang = store.getValue("home_screen_result")
// Extract data from the boomerang
val selectedItem = boomerang?.getString("selectedItem")
val quantity = boomerang?.getInt("quantity")
Catching a Value
// Try to catch a value using a BoomerangCatcher
store.tryConsumeValue("home_screen_result") { boomerang ->
// Process the boomerang
val selectedItem = boomerang.getString("selectedItem")
val quantity = boomerang.getInt("quantity")
// Return true to indicate the value was successfully caught and should be removed
true
}
Storing and Catching Events
// Store an event notification
store.storeEvent("notification_event")
// Create an event catcher
val eventCatcher = eventBoomerangCatcher("notification_event") {
// This callback is executed when the event is caught
println("Event received!")
}
// Try to catch the event
store.tryConsumeValue("notification_event", eventCatcher)
Saving and Restoring State
// Pack the store's state into a Boomerang object
val stateBoomerang = store.packState()
// Later, restore the store from the saved state
val restoredStore = DefaultBoomerangStore().apply {
restoreState(stateBoomerang)
}
Configuring Logging
// For Android applications
BoomerangConfig.logger = AndroidBoomerangLogger(LogLevel.DEBUG)
// For other platforms or simple console logging
BoomerangConfig.logger = BoomerangLogger.PRINT_LOGGER
// Create a custom logger
val customLogger = object : BoomerangLogger {
override fun log(tag: String, message: String) {
// Integrate with your preferred logging system
YourLoggingSystem.log("$tag: $message")
}
}
BoomerangConfig.logger = customLogger
// Disable logging
BoomerangConfig.logger = null
When logging is enabled, Boomerang will log operations like storing and retrieving values, which can be helpful for debugging navigation flows and understanding how data is being passed between screens.
Advanced Usage
Custom BoomerangStore Implementation
You can create your own implementation of the BoomerangStore
interface if you need custom behavior:
class MyCustomBoomerangStore : BoomerangStore {
// Custom implementation of BoomerangStore methods
}
Custom BoomerangCatcher Implementation
You can create a reusable BoomerangCatcher
implementation:
val myCatcher = BoomerangCatcher { bundle: Bundle ->
// Process the bundle
true // Return true to indicate the value was successfully caught
}
// Use the catcher
store.tryCatch("some_key", myCatcher)
Platform-Specific Implementations
The Core module provides platform-specific implementations of the Boomerang
interface:
Android
On Android, the AndroidBoomerang
class implements the Boomerang
interface using Android's Bundle for storage. This provides efficient integration with Android's saved instance state mechanism.
iOS and Desktop
On iOS and Desktop, the MapBoomerang
class implements the Boomerang
interface using a MutableMap for storage. This provides a lightweight and efficient storage mechanism for these platforms.
The BoomerangFactory
object provides a platform-specific factory for creating the appropriate Boomerang
implementation for the current platform.
Requirements
Kotlin 1.5.0+
Platform-specific requirements:
Android: API level 21+
iOS: iOS 14+
Desktop: JVM 11+
License
Copyright 2025 Buszi
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
A lightweight multiplatform library providing the fundamental concepts and interfaces for handling navigation results in applications.
Overview
The Core module of Boomerang contains the essential components that power both the Compose and Fragment modules. It defines the key interfaces and classes for storing, retrieving, and processing navigation results between screens without tight coupling between components.
This module supports Android, iOS, and Desktop platforms, providing a consistent API across all platforms while using platform-specific implementations under the hood.
Installation
Add the following dependency to your app's build.gradle.kts
file:
// For core functionality (required by all Boomerang modules)
implementation("io.github.buszi.boomerang:core:1.4.0")
The Core module is required by both the Compose and Fragment modules, so you'll need to include it regardless of which integration you're using.
Key Components
BoomerangStore
The BoomerangStore
interface defines a key-value store for navigation results:
interface BoomerangStore {
fun getValue(key: String): Boomerang?
fun storeValue(key: String, value: Boomerang)
fun storeEvent(key: String)
fun dropValue(key: String)
fun tryConsumeValue(key: String, catcher: BoomerangCatcher)
fun packState(): Boomerang
fun restoreState(boomerang: Boomerang)
}
This interface provides methods for:
Retrieving a value for a key (
getValue
)Storing a value with a key (
storeValue
)Storing an event notification with a key (
storeEvent
)Removing a value for a key (
dropValue
)Trying to catch a value using a
BoomerangCatcher
(tryConsumeValue
)Packing the store's state into a Boomerang object (
packState
)Restoring the store's state from a Boomerang object (
restoreState
)
BoomerangCatcher
The BoomerangCatcher
functional interface is used for catching and processing Boomerang values:
fun interface BoomerangCatcher {
fun tryCatch(value: Boomerang): Boolean
}
Implementations of this interface determine whether a Boomerang value should be "caught" (processed and removed from the store).
EventBoomerangCatcher
The eventBoomerangCatcher
function creates a specialized BoomerangCatcher
for handling event notifications:
inline fun eventBoomerangCatcher(
key: String,
crossinline onEvent: () -> Unit,
): BoomerangCatcher
This function is useful when you only need to be notified that something happened, without needing to pass any additional data. It checks if the Boomerang contains an event with the specified key and calls the provided callback when the event is caught.
DefaultBoomerangStore
The DefaultBoomerangStore
class is the default implementation of the BoomerangStore
interface:
class DefaultBoomerangStore : BoomerangStore {
// Implementation of BoomerangStore methods
}
The DefaultBoomerangStore
uses a private mutable map to store key-value pairs and provides methods for packing and restoring its state. It's designed to work across all supported platforms (Android, iOS, Desktop).
BoomerangStoreHost
The BoomerangStoreHost
interface is for components that host a BoomerangStore
:
interface BoomerangStoreHost {
var boomerangStore: BoomerangStore?
}
This interface is typically implemented by Activities or other lifecycle-aware components that need to provide a BoomerangStore
to their children.
Logging Components
Boomerang provides optional logging capabilities to help with debugging:
BoomerangLogger
The BoomerangLogger
interface defines a simple logging mechanism:
interface BoomerangLogger {
fun log(tag: String, message: String)
}
This interface can be implemented by applications to integrate with their preferred logging system.
BoomerangConfig
The BoomerangConfig
object provides global configuration options:
object BoomerangConfig {
var logger: BoomerangLogger? = null
}
By default, logger
is null
, which means logging is disabled. To enable logging, set this property to an instance of BoomerangLogger
.
AndroidBoomerangLogger
For Android applications, Boomerang provides an Android-specific logger that integrates with Android's Log utility:
class AndroidBoomerangLogger(
private val level: LogLevel = LogLevel.DEBUG
) : BoomerangLogger
The LogLevel
enum defines the available log levels (VERBOSE, DEBUG, INFO, WARN, ERROR).
Usage
The Core module is not typically used directly in your application code. Instead, you'll use either the Compose or Fragment modules, which provide integration with their respective UI frameworks.
However, if you're building a custom integration or need direct access to the core functionality, you can use the Core module as follows:
Creating a Store
// Create a new DefaultBoomerangStore
val store = DefaultBoomerangStore()
Storing a Value
// Store the result with a key using the builder pattern
store.storeValue("home_screen_result") {
putString("selectedItem", "Item 1")
putInt("quantity", 5)
}
Retrieving a Value
// Get a value for a key
val boomerang = store.getValue("home_screen_result")
// Extract data from the boomerang
val selectedItem = boomerang?.getString("selectedItem")
val quantity = boomerang?.getInt("quantity")
Catching a Value
// Try to catch a value using a BoomerangCatcher
store.tryConsumeValue("home_screen_result") { boomerang ->
// Process the boomerang
val selectedItem = boomerang.getString("selectedItem")
val quantity = boomerang.getInt("quantity")
// Return true to indicate the value was successfully caught and should be removed
true
}
Storing and Catching Events
// Store an event notification
store.storeEvent("notification_event")
// Create an event catcher
val eventCatcher = eventBoomerangCatcher("notification_event") {
// This callback is executed when the event is caught
println("Event received!")
}
// Try to catch the event
store.tryConsumeValue("notification_event", eventCatcher)
Saving and Restoring State
// Pack the store's state into a Boomerang object
val stateBoomerang = store.packState()
// Later, restore the store from the saved state
val restoredStore = DefaultBoomerangStore().apply {
restoreState(stateBoomerang)
}
Configuring Logging
// For Android applications
BoomerangConfig.logger = AndroidBoomerangLogger(LogLevel.DEBUG)
// For other platforms or simple console logging
BoomerangConfig.logger = BoomerangLogger.PRINT_LOGGER
// Create a custom logger
val customLogger = object : BoomerangLogger {
override fun log(tag: String, message: String) {
// Integrate with your preferred logging system
YourLoggingSystem.log("$tag: $message")
}
}
BoomerangConfig.logger = customLogger
// Disable logging
BoomerangConfig.logger = null
When logging is enabled, Boomerang will log operations like storing and retrieving values, which can be helpful for debugging navigation flows and understanding how data is being passed between screens.
Advanced Usage
Custom BoomerangStore Implementation
You can create your own implementation of the BoomerangStore
interface if you need custom behavior:
class MyCustomBoomerangStore : BoomerangStore {
// Custom implementation of BoomerangStore methods
}
Custom BoomerangCatcher Implementation
You can create a reusable BoomerangCatcher
implementation:
val myCatcher = BoomerangCatcher { bundle: Bundle ->
// Process the bundle
true // Return true to indicate the value was successfully caught
}
// Use the catcher
store.tryCatch("some_key", myCatcher)
Platform-Specific Implementations
The Core module provides platform-specific implementations of the Boomerang
interface:
Android
On Android, the AndroidBoomerang
class implements the Boomerang
interface using Android's Bundle for storage. This provides efficient integration with Android's saved instance state mechanism.
iOS and Desktop
On iOS and Desktop, the MapBoomerang
class implements the Boomerang
interface using a MutableMap for storage. This provides a lightweight and efficient storage mechanism for these platforms.
The BoomerangFactory
object provides a platform-specific factory for creating the appropriate Boomerang
implementation for the current platform.
Requirements
Kotlin 1.5.0+
Platform-specific requirements:
Android: API level 21+
iOS: iOS 14+
Desktop: JVM 11+
License
Copyright 2025 Buszi
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.