Compose Multiplatform runtime library for iOS UIKit x64 target providing core runtime functionality for declarative UI framework integration.
—
Core state management functionality providing reactive state holders and automatic change detection. The state system enables building dynamic UIs that automatically recompose when data changes.
Creates mutable state holders that trigger recomposition when their values change.
/**
* Creates a MutableState<T> initialized with the given value
* @param value Initial value for the state
* @return MutableState that triggers recomposition on value changes
*/
fun <T> mutableStateOf(value: T): MutableState<T>
/**
* Creates a MutableState<T> with a specific SnapshotMutationPolicy
* @param value Initial value for the state
* @param policy Custom equality policy for change detection
* @return MutableState with custom mutation policy
*/
fun <T> mutableStateOf(
value: T,
policy: SnapshotMutationPolicy<T>
): MutableState<T>Usage Examples:
import androidx.compose.runtime.*
@Composable
fun StateExample() {
// Basic mutable state
var counter by remember { mutableStateOf(0) }
var text by remember { mutableStateOf("") }
var isVisible by remember { mutableStateOf(true) }
// Custom objects
var user by remember { mutableStateOf(User("", "")) }
// Lists
var items by remember { mutableStateOf(listOf<String>()) }
}
data class User(val name: String, val email: String)Creates computed state that recalculates when its dependencies change.
/**
* Creates a State<T> that recalculates when dependencies change
* @param calculation Function that computes the derived value
* @return State that automatically updates when dependencies change
*/
fun <T> derivedStateOf(calculation: () -> T): State<T>
/**
* Creates a State<T> with a custom SnapshotMutationPolicy
* @param policy Custom equality policy for change detection
* @param calculation Function that computes the derived value
* @return State with custom derived computation policy
*/
fun <T> derivedStateOf(
policy: SnapshotMutationPolicy<T>,
calculation: () -> T
): State<T>Usage Examples:
@Composable
fun DerivedStateExample() {
var firstName by remember { mutableStateOf("") }
var lastName by remember { mutableStateOf("") }
// Derived state automatically recalculates when firstName or lastName change
val fullName by remember {
derivedStateOf { "$firstName $lastName".trim() }
}
val isValidName by remember {
derivedStateOf { fullName.length >= 2 }
}
TextField(value = firstName, onValueChange = { firstName = it })
TextField(value = lastName, onValueChange = { lastName = it })
Text("Full name: $fullName")
Button(enabled = isValidName) { Text("Submit") }
}Core interfaces for state management.
/**
* Read-only state holder
*/
interface State<out T> {
/** Current value of the state */
val value: T
}
/**
* Mutable state holder that triggers recomposition on changes
*/
interface MutableState<T> : State<T> {
/** Current mutable value of the state */
override var value: T
/**
* Returns a new component1 for destructuring declarations
* @return Current value
*/
operator fun component1(): T
/**
* Returns a new component2 for destructuring declarations
* @return Setter function for the state
*/
operator fun component2(): (T) -> Unit
}
/**
* Default implementation of MutableState using the snapshot system
*/
interface SnapshotMutableState<T> : MutableState<T> {
/** The SnapshotMutationPolicy used by this state */
val policy: SnapshotMutationPolicy<T>
}Kotlin property delegate support for convenient state access.
/**
* Property delegate getter for State<T>
* @param thisObj The object containing the property (unused)
* @param property Metadata about the property (unused)
* @return Current value of the state
*/
operator fun <T> State<T>.getValue(
thisObj: Any?,
property: KProperty<*>
): T
/**
* Property delegate setter for MutableState<T>
* @param thisObj The object containing the property (unused)
* @param property Metadata about the property (unused)
* @param value New value to set
*/
operator fun <T> MutableState<T>.setValue(
thisObj: Any?,
property: KProperty<*>,
value: T
): UnitUsage Examples:
@Composable
fun PropertyDelegateExample() {
// Using property delegates with 'by'
var name by remember { mutableStateOf("") }
var age by remember { mutableStateOf(0) }
// Equivalent to:
// val nameState = remember { mutableStateOf("") }
// var name: String
// get() = nameState.value
// set(value) { nameState.value = value }
}Convert state reads into Kotlin coroutine Flows.
/**
* Creates a Flow that emits the result of block whenever observed state changes
* @param block Function that reads state and produces values
* @return Flow that emits when any observed state changes
*/
fun <T> snapshotFlow(block: () -> T): Flow<T>Usage Examples:
@Composable
fun FlowIntegrationExample() {
var searchQuery by remember { mutableStateOf("") }
LaunchedEffect(Unit) {
snapshotFlow { searchQuery }
.debounce(300)
.collect { query ->
if (query.isNotEmpty()) {
performSearch(query)
}
}
}
}State management that survives process death and configuration changes, essential for iOS applications.
/**
* Creates persistent state that survives process death and configuration changes
* Equivalent to remember but persists across app restarts
* @param value Initial value for the state
* @param saver Custom Saver for serialization, uses auto-saver if null
* @return MutableState that persists across process death
*/
@Composable
fun <T> rememberSaveable(
vararg inputs: Any?,
saver: Saver<T, out Any>? = null,
init: () -> T
): T
/**
* Creates persistent mutable state with initial value
* @param value Initial value for the state
* @param saver Custom Saver for serialization
* @return MutableState that persists across process death
*/
@Composable
fun <T> rememberSaveable(
value: T,
saver: Saver<T, out Any>? = null
): MutableState<T>Usage Examples:
@Composable
fun PersistentStateExample() {
// Survives iOS app backgrounding and termination
var userName by rememberSaveable { mutableStateOf("") }
var userId by rememberSaveable { mutableStateOf(0) }
// Custom object with custom saver
var userProfile by rememberSaveable(
saver = UserProfileSaver
) { mutableStateOf(UserProfile()) }
TextField(
value = userName,
onValueChange = { userName = it },
label = { Text("Username") }
)
}
object UserProfileSaver : Saver<UserProfile, Bundle> {
override fun restore(value: Bundle): UserProfile? =
UserProfile.fromBundle(value)
override fun SaverScope.save(value: UserProfile): Bundle? =
value.toBundle()
}Create state from asynchronous data sources like network calls or databases.
/**
* Creates state that is produced by an async operation
* @param initialValue Initial value while async operation is running
* @param key1 Key that triggers recreation of the producer
* @param producer Suspend function that produces the state value
* @return State that updates when async operation completes
*/
@Composable
fun <T> produceState(
initialValue: T,
key1: Any?,
producer: suspend ProduceStateScope<T>.() -> Unit
): State<T>
/**
* Scope for produceState operations
*/
interface ProduceStateScope<T> : MutableState<T>, CoroutineScope {
/** Awaits the coroutine to complete before disposing */
suspend fun awaitDispose(onDispose: () -> Unit)
}Usage Examples:
@Composable
fun AsyncStateExample(userId: String) {
val userState by produceState(
initialValue = User.Empty,
key1 = userId
) {
// Suspend function that loads user data
value = userRepository.loadUser(userId)
}
val networkState by produceState(
initialValue = NetworkState.Loading
) {
try {
val data = apiService.fetchData()
value = NetworkState.Success(data)
} catch (e: Exception) {
value = NetworkState.Error(e.message)
}
}
when (networkState) {
is NetworkState.Loading -> LoadingIndicator()
is NetworkState.Success -> DataDisplay(networkState.data)
is NetworkState.Error -> ErrorMessage(networkState.message)
}
}Convert Kotlin coroutine Flows to Compose State for reactive UI updates.
/**
* Collects values from a Flow and represents them as State
* @param initial Initial value before first emission
* @param context CoroutineContext for collection, uses current recomposition context by default
* @return State that reflects the latest Flow emission
*/
@Composable
fun <T> Flow<T>.collectAsState(
initial: T,
context: CoroutineContext = EmptyCoroutineContext
): State<T>
/**
* Collects values from a Flow as State with lifecycle awareness
* @param initial Initial value before first emission
* @param lifecycle Lifecycle to respect for collection
* @param minActiveState Minimum lifecycle state for active collection
* @param context CoroutineContext for collection
* @return State that reflects the latest Flow emission
*/
@Composable
fun <T> Flow<T>.collectAsStateWithLifecycle(
initial: T,
lifecycle: Lifecycle,
minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
context: CoroutineContext = EmptyCoroutineContext
): State<T>Usage Examples:
@Composable
fun FlowStateExample() {
val viewModel: UserViewModel = viewModel()
// Collect Flow as State
val users by viewModel.usersFlow.collectAsState(initial = emptyList())
val isLoading by viewModel.loadingFlow.collectAsState(initial = false)
// Display users
LazyColumn {
items(users) { user ->
UserItem(user = user)
}
}
if (isLoading) {
LoadingOverlay()
}
}
class UserViewModel : ViewModel() {
private val _users = MutableStateFlow<List<User>>(emptyList())
val usersFlow: StateFlow<List<User>> = _users.asStateFlow()
private val _loading = MutableStateFlow(false)
val loadingFlow: StateFlow<Boolean> = _loading.asStateFlow()
}/**
* Policy for determining when state changes should trigger recomposition
*/
interface SnapshotMutationPolicy<T> {
/**
* Determines if the current and new values are equivalent
* @param a Current value
* @param b New value
* @return true if values are equivalent and shouldn't trigger recomposition
*/
fun equivalent(a: T, b: T): Boolean
/**
* Merges conflicting changes during snapshot conflicts
* @param previous Previous value
* @param current Current value
* @param applied Value being applied
* @return Merged value or null if merge is not possible
*/
fun merge(previous: T, current: T, applied: T): T?
}
/** Built-in policies */
object SnapshotMutationPolicy {
/** Uses structural equality (==) for comparison */
fun <T> structuralEquality(): SnapshotMutationPolicy<T>
/** Uses referential equality (===) for comparison */
fun <T> referentialEquality(): SnapshotMutationPolicy<T>
/** Never considers values equivalent, always triggers recomposition */
fun <T> neverEqual(): SnapshotMutationPolicy<T>
}derivedStateOf instead of remember for computed valuesInstall with Tessl CLI
npx tessl i tessl/maven-org-jetbrains-compose-runtime--runtime-uikitx64