Integrating the Journey module with Jetpack Compose
PingOne Advanced Identity Cloud PingAM Android
If your application uses Jetpack Compose, you can seamlessly integrate the Journey module by using a ViewModel to manage the UI state:
ViewModel
Using the Journey module with a JetPack Compose ViewModel
class AuthViewModel : ViewModel() {
private val _state = MutableStateFlow<Node>(Empty)
val state: StateFlow<Node> = _state
private lateinit var journey: Journey // Initialize your Journey instance
fun initializeJourney() {
journey = Journey {
// Configure your Journey instance here
serverUrl = "https://openam-forgerock-sdks.forgeblocks.com/am"
// ... other configurations
}
}
fun startJourney(flowName: String = "sdkUsernamePasswordJourney") {
viewModelScope.launch {
val nextNode = journey.start(flowName)
_state.update { nextNode }
}
}
fun next(node: ContinueNode, input: Map<String, String> = emptyMap()) {
viewModelScope.launch {
val nextNode = node.next(input)
_state.update { nextNode }
}
}
}
View (Composable)
Using the Journey module with a composable view
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun AuthScreen() {
val viewModel: AuthViewModel = viewModel()
val authState by viewModel.state.collectAsState()
// Initialize Journey when the composable is created
LaunchedEffect(key1 = Unit) {
viewModel.initializeJourney()
viewModel.startJourney()
}
when (val node = authState) {
is ContinueNode -> {
// Render UI elements based on the callbacks in the node
// Example: Display text fields for NameCallback and PasswordCallback
val callbacks = node.callbacks
// ... UI logic to collect user input and call viewModel.handleCallbacks()
}
is ErrorNode -> {
// Display the error message
Text(text = "Authentication Error: ${node.message}")
}
is FailureNode -> {
// Display a generic error message
Text(text = "An unexpected error occurred.")
// Optionally log the errorCause
Log.e("AuthScreen", "Authentication Failure", node.cause)
}
is SuccessNode -> {
// Navigate to the main application screen
Text(text = "Authentication Successful!")
// ... Navigation logic
}
}
}