DaVinci client sample apps
We provide the source code for sample applications that demonstrate how to integrate DaVinci flows into your mobile and web applications using the DaVinci client.
You can clone or download the sample source code from our GitHub repository at https://github.com/ForgeRock/sdk-sample-apps.
Each sample is a functional application designed to provide a practical guide for common integration scenarios. You can use them as a reference to understand key concepts or as a starting point for your own custom implementation.
|
The sample applications are provided "as is" for demonstration purposes only. They are not official products of Ping Identity and are not officially supported. |
We provide DaVinci client sample apps for the following platforms:
Android sample apps
kotlin-davinci
What does the kotlin-davinci sample support?
| Feature | Supported by sample |
|---|---|
Orchestration |
|
Implementation |
|
Language |
|
DaVinci Fields |
|
DaVinci Buttons |
|
DaVinci Toolbox |
|
The kotlin-davinci application is a lightweight Android client.
It is designed to demonstrate a core capability of the DaVinci client for Android: rendering a dynamic user interface based on signals received from a DaVinci flow.
Instead of having a hardcoded login screen, the app starts a DaVinci flow and waits for the server to send instructions on what to display. It then constructs the UI on-the-fly, whether it’s a username/password form, a message, or other interactive elements defined in your DaVinci flow.
The application’s code showcases several important implementation patterns for integrating with DaVinci:
1. Dynamic UI Rendering with Jetpack Compose
The app uses modern Android development practices, leveraging Jetpack Compose to build its user interface. The core logic resides in the DaVinciScreen.kt file.
-
It observes a state object from the
DaVinciViewModel. -
It uses a
whenstatement to react to the current state of the DaVinci flow (Login,Success, orFailure). -
For the
Loginstate, it iterates through the list of collectors returned from the DaVinci flow and renders the appropriate Composable for each one.This is the dynamic part—if you change the DaVinci flow the UI will change without needing to recompile the app.
2. State Management with ViewModel and StateFlow
The application follows the recommended Android architecture by separating UI logic from business logic.
-
DaVinciViewModel.ktis responsible for all interactions with the Ping Identity SDK. -
It uses a
MutableStateFlowto hold the current state of the DaVinci flow (DaVinciAction). The UI (Composable functions) subscribes to this flow and automatically updates whenever the state changes.This decouples the SDK interaction from the UI, making the code cleaner and easier to test.
3. SDK Initialization and Configuration
The app demonstrates how to initialize and configure the SDK to connect to your specific PingOne and DaVinci environment. In DaVinciViewModel, it shows how to:
-
Provide the necessary DaVinci client configuration
-
Start the DaVinci flow by calling
start().
4. Handling User Input
The sample shows how to collect data from the dynamically rendered input fields, such as username and password fields, package it into a Map, and submit it back to DaVinci using the action.next() method.
This is the mechanism for advancing the flow after a user provides their credentials or makes a choice.
iOS sample apps
swiftui-davinci
What does the swiftui-davinci sample support?
| Feature | Supported by sample |
|---|---|
Orchestration |
|
Implementation |
|
Language |
|
DaVinci Fields |
|
DaVinci Buttons |
|
The swiftui-davinci application is a modern iOS client built with Swift and SwiftUI.
It’s designed to demonstrate a core capability of the DaVinci client for iOS: rendering a dynamic user interface based on collectors received from a DaVinci flow.
Instead of having a hardcoded login screen, the app initiates a DaVinci flow and waits for the server to send collectors, which describe the required data. It then constructs the UI on-the-fly, whether it’s a username and password form, a message, or other interactive elements defined in your DaVinci flow.
The application’s code showcases several important implementation patterns for integrating with DaVinci using modern iOS development practices:
1. Dynamic UI Rendering with SwiftUI
The app uses SwiftUI to build its user interface declaratively. The core rendering logic resides in ContentView.swift.
-
It observes a state object from the
DavinciViewModel. -
It uses a
switchstatement to react to the current state of the DaVinci flow, either.loading,.loaded, or.success). -
For the
.loadedstate, it iterates through an array of collectors returned by the DaVinci flow and renders the appropriate SwiftUI View for each one.This is the dynamic part—if you change the DaVinci flow on the server, the UI will change without needing to recompile the app.
2. State Management with Combine and ViewModel
The application follows the recommended MVVM (Model-View-ViewModel) architecture by separating UI logic from business logic.
-
DavinciViewModel.swiftis responsible for interactions with the DaVinci client for iOS. -
It uses
@Published propertiesfrom the Combine framework to hold the current state of the DaVinci flow, such asflowStateandinputs. The SwiftUIViewsubscribes to these properties and automatically updates whenever their values change.This decouples the SDK interaction from the UI, making the code cleaner and easier to manage.
3. SDK Initialization and Configuration
The app demonstrates how to initialize and configure the SDK to connect to your specific PingOne and DaVinci environment.
-
Provide the necessary DaVinci client configuration
-
Start the DaVinci flow by calling the
start()method.
4. Handling User Input and Flow Progression
The sample shows how to collect data from the dynamically rendered input fields, bind it to a dictionary in the ViewModel, and submit it back to DaVinci.
This is the mechanism for advancing the flow after a user provides their credentials or makes a choice.
JavaScript sample apps
reactjs-todo-davinci
What does the reactjs-todo-davinci sample support?
| Feature | Supported by sample |
|---|---|
Orchestration |
|
Implementation |
|
Language |
|
DaVinci Fields |
|
DaVinci Buttons |
|
DaVinci Toolbox |
|
The reactjs-todo-davinci application is a "To-Do List" single-page application (SPA) built with ReactJS.
Its primary purpose is to demonstrate how to secure a React application by embedding a PingOne DaVinci flow directly into the user experience.
Instead of a static login form, the application initiates a DaVinci flow and dynamically renders the necessary UI components based on the collectors it receives from the server. Once a user is authenticated, they can access the protected To-Do list page, showcasing a complete, secure workflow from login to application usage.
|
This sample optionally uses the |
The application showcases several modern, best-practice patterns for integrating the DaVinci client for JavaScript within a React project:
1. Global State Management with React Context
The application uses React’s built-in Context API for managing shared state, which is a lightweight and effective alternative to larger libraries like Redux for this use case.
-
Location:
javascript/reactjs-todo-davinci/client/global-state.js -
Function: It defines a custom hook,
useGlobalStateMgmt, which encapsulates all the logic for managing shared state likeisAuthenticated,username, andtheme. TheAppContextthen makes this state and its setter functions available to any component wrapped in its provider.The
setAuthenticationWrapperfunction couples the application’s state with the DaVinci client’s functionality. When a component sets the authentication state tofalse, this wrapper interprets it as a logout action and triggerslogout(), ensuring the user’s session is properly terminated PingOne.
2. Dynamic, View-Based Routing
The application uses react-router-dom to manage navigation, with a structure that separates public and private views.
-
File:
javascript/reactjs-todo-davinci/client/router.js -
Function: The
Routercomponent defines all application routes. It makes use of a customProtectedRoutecomponent to guard access to the/todospage.This guard checks the
isAuthenticatedflag from the global context and redirects unauthenticated users to the/loginpage.
3. Component-Driven DaVinci Flow
The login experience is not hardcoded but is driven by the DaVinci flow itself.
-
File:
javascript/reactjs-todo-davinci/client/views/login.js -
Function: The
Loginview acts as a container. It renders a dedicated<Form />component (refer tojavascript/reactjs-todo-davinci/client/components/davinci-client/form.js).This
Formcomponent is responsible for initiating the DaVinci flow, listening for collectors, and dynamically rendering the appropriate input fields, such as a username and password. This architecture makes the login UI incredibly flexible, as the entire user journey can be modified in the DaVinci flow builder without changing the React code.