### Compose Multiplatform Biometric Authentication Setup
Source: https://context7.com/icerockdev/moko-biometry/llms.txt
This code demonstrates setting up biometric authentication in a Compose Multiplatform application. It uses `rememberBiometryAuthenticatorFactory()` to get a platform-aware factory and `BindBiometryAuthenticatorEffect` for necessary Android lifecycle binding.
```kotlin
@Composable
fun BiometricLoginScreen() {
val biometryFactory: BiometryAuthenticatorFactory = rememberBiometryAuthenticatorFactory()
val viewModel = remember {
AuthViewModel(
biometryAuthenticator = biometryFactory.createBiometryAuthenticator()
)
}
BindBiometryAuthenticatorEffect(viewModel.biometryAuthenticator)
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Button(onClick = { viewModel.performBiometricLogin() }) {
Text("Login with Biometrics")
}
}
}
```
--------------------------------
### iOS ViewController Integration for Biometry (Swift)
Source: https://github.com/icerockdev/moko-biometry/blob/master/README.md
Provides a Swift example for integrating Moko-Biometry into an iOS `UIViewController`. It shows how to initialize the `SampleViewModel` with a platform-specific `BiometryBiometryAuthenticator` and trigger the authentication process via an IBAction.
```swift
class SampleViewController: UIViewController {
private var viewModel: SampleViewModel!
override func viewDidLoad() {
super.viewDidLoad()
self.viewModel = SampleViewModel(
biometryAuthenticator: BiometryBiometryAuthenticator(),
)
}
@IBAction private func loginAction() {
self.viewModel.tryToAuth()
}
}
```
--------------------------------
### Moko Biometry Dependency Setup in Gradle
Source: https://github.com/icerockdev/moko-biometry/blob/master/README.md
This Groovy script demonstrates how to add the Moko Biometry library and its Compose Multiplatform extension to your project's dependencies in the project-level build.gradle file. It specifies the commonMain API for multiplatform usage and also shows an option for Jetpack Compose on Android if not using multiplatform.
```groovy
dependencies {
commonMainApi("dev.icerock.moko:biometry:0.4.0")
// Compose Multiplatform
commonMainApi("dev.icerock.moko:biometry-compose:0.4.0")
// Jetpack Compose (only for android, if you don't use multiplatform)
implementation("dev.icerock.moko:biometry-compose:0.4.0")
}
```
--------------------------------
### Android Compose Activity Setup for Biometrics
Source: https://context7.com/icerockdev/moko-biometry/llms.txt
Configures an Android Activity to support biometric authentication within Jetpack Compose. The Activity must extend `FragmentActivity` instead of `ComponentActivity` to correctly display the biometric prompt dialog. This setup includes initializing the `BiometryAuthenticator` and binding it to the Activity's lifecycle using `BindBiometryAuthenticatorEffect`.
```kotlin
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.fragment.app.FragmentActivity
import dev.icerock.moko.biometry.compose.BindBiometryAuthenticatorEffect
import dev.icerock.moko.biometry.compose.rememberBiometryAuthenticatorFactory
import kotlinx.coroutines.launch
// Dummy extension function for demonstration
fun String.desc(): String = this
// Dummy AuthViewModel for demonstration
class AuthViewModel(val biometryAuthenticator: BiometryAuthenticator) {
// ViewModel logic here
}
// Android - MainActivity.kt for Compose
class MainActivity : FragmentActivity() { // Must be FragmentActivity, not ComponentActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
val biometryFactory = rememberBiometryAuthenticatorFactory()
val viewModel = remember {
AuthViewModel(
biometryAuthenticator = biometryFactory.createBiometryAuthenticator()
)
}
// Bind to lifecycle - connects to FragmentActivity
BindBiometryAuthenticatorEffect(viewModel.biometryAuthenticator)
BiometricLoginContent(viewModel = viewModel)
}
}
}
}
@Composable
fun BiometricLoginContent(viewModel: AuthViewModel) {
var resultText by remember { mutableStateOf("Ready to authenticate") }
val scope = rememberCoroutineScope()
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = resultText)
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = {
scope.launch {
resultText = "Authenticating..."
try {
val success = viewModel.biometryAuthenticator.checkBiometryAuthentication(
requestTitle = "Verify Identity".desc(),
requestReason = "Please authenticate to proceed".desc(),
failureButtonText = "Use Password".desc(),
allowDeviceCredentials = false
)
resultText = if (success) "Success!" else "Cancelled"
} catch (e: Throwable) {
resultText = "Error: ${e.message}"
}
}
}) {
Text("Authenticate with Biometrics")
}
}
}
```
--------------------------------
### Android Compose Activity Integration for Biometry (Kotlin)
Source: https://github.com/icerockdev/moko-biometry/blob/master/README.md
Illustrates how to integrate Moko-Biometry with Jetpack Compose in an Android Activity. This example extends `FragmentActivity`, uses `rememberBiometryAuthenticatorFactory` to create the authenticator, and employs `BindBiometryAuthenticatorEffect` to manage the authenticator's lifecycle within the Compose UI.
```kotlin
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setContent {
val biometryFactory: BiometryAuthenticatorFactory = rememberBiometryAuthenticatorFactory()
// Create viewModel from common code
val viewModel = getViewModel {
SampleViewModel(
// Pass platform implementation of the Biometry Authenticator
// to a common code
biometryAuthenticator = biometryFactory.createBiometryAuthenticator()
)
}
// Binds the Biometry Authenticator to the view lifecycle
BindBiometryAuthenticatorEffect(viewModel.biometryAuthenticator)
// Same screen content here
}
}
}
```
--------------------------------
### iOS Biometry Integration and Info.plist Configuration
Source: https://context7.com/icerockdev/moko-biometry/llms.txt
For iOS, BiometryAuthenticator can be created directly without binding. It's crucial to add the NSFaceIDUsageDescription key to Info.plist to inform users about Face ID usage. This Swift code shows the ViewController setup.
```swift
import UIKit
import MultiPlatformLibrary
class LoginViewController: UIViewController {
private var viewModel: AuthViewModel!
override func viewDidLoad() {
super.viewDidLoad()
self.viewModel = AuthViewModel(
biometryAuthenticator: BiometryBiometryAuthenticator()
)
}
@IBAction private func loginButtonTapped() {
self.viewModel.performBiometricLogin()
}
}
// Info.plist - Add Face ID usage description (required for Face ID)
// NSFaceIDUsageDescription
// $(PRODUCT_NAME) uses Face ID to securely authenticate you
```
--------------------------------
### Create ViewModel for Biometric Authentication (Kotlin)
Source: https://github.com/icerockdev/moko-biometry/blob/master/README.md
Demonstrates how to create a ViewModel in common Kotlin code that utilizes the BiometryAuthenticator. It includes a function to initiate biometric authentication with customizable request details and handles success or failure callbacks. This is the core logic that can be shared across platforms.
```kotlin
class SampleViewModel(
val biometryAuthenticator: BiometryAuthenticator
) : ViewModel() {
fun tryToAuth() = viewModelScope.launch {
try {
val isSuccess = biometryAuthenticator.checkBiometryAuthentication(
requestTitle = "Biometry".desc(),
requestReason = "Just for test".desc(),
failureButtonText = "Oops".desc(),
allowDeviceCredentials = false // true - if biometric permission is not granted user can authorise by device creds
)
if (isSuccess) {
// Do something onSuccess
}
} catch (throwable: Throwable) {
// Do something onFailed
}
}
}
```
--------------------------------
### Android Activity Integration for Biometry (Kotlin)
Source: https://github.com/icerockdev/moko-biometry/blob/master/README.md
Shows how to integrate the common ViewModel with BiometryAuthenticator into an Android Activity. It covers creating the ViewModel, passing the platform-specific `applicationContext`, and binding the authenticator to the Activity's lifecycle for proper management.
```kotlin
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: SampleViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Create viewModel from common code.
viewModel = getViewModel {
SampleViewModel(
// Pass platform implementation of the Biometry Authenticator
// to a common code
biometryAuthenticator = BiometryAuthenticator(
applicationContext = applicationContext
)
)
}
// Binds the Biometry Authenticator to the view lifecycle
viewModel.biometryAuthenticator.bind(
lifecycle = this@MainActivity.lifecycle,
fragmentManager = supportFragmentManager
)
}
}
```
--------------------------------
### Project-Level Gradle Configuration for Moko Biometry
Source: https://github.com/icerockdev/moko-biometry/blob/master/README.md
This Groovy script configures the root build.gradle file to include Maven Central as a repository, which is necessary for resolving dependencies like Moko Biometry.
```groovy
allprojects {
repositories {
mavenCentral()
}
}
```
--------------------------------
### iOS Info.plist Configuration for Biometry (XML)
Source: https://github.com/icerockdev/moko-biometry/blob/master/README.md
This snippet shows the necessary addition to your iOS project's `Info.plist` file. It includes the `NSFaceIDUsageDescription` key, which is required to explain to the user why your app needs access to Face ID or Touch ID.
```xml
NSFaceIDUsageDescription
$(PRODUCT_NAME) Authentication with TouchId or FaceID
```
--------------------------------
### Compose Multiplatform Biometry Screen (Kotlin)
Source: https://github.com/icerockdev/moko-biometry/blob/master/README.md
Demonstrates a composable function for a Biometry screen in a Compose Multiplatform application. It utilizes `rememberBiometryAuthenticatorFactory` and `getViewModel` to set up the ViewModel and `BindBiometryAuthenticatorEffect` to bind the authenticator to the composable's lifecycle, displaying authentication status and a button to trigger the action.
```kotlin
@Composable
fun BiometryScreen() {
val biometryFactory: BiometryAuthenticatorFactory = rememberBiometryAuthenticatorFactory()
BiometryScreen(
viewModel = getViewModel(
key = "biometry-screen",
factory = viewModelFactory {
BiometryViewModel(
biometryAuthenticator = biometryAuthenticatorFactory.createBiometryAuthenticator()
)
}
)
)
}
@Composable
private fun BiometryScreen(
viewModel: BiometryViewModel
) = NavigationScreen(title = "moko-biometry") { paddingValues ->
BindBiometryAuthenticatorEffect(viewModel.biometryAuthenticator)
val text: String by viewModel.result.collectAsState()
Column(
modifier = Modifier.fillMaxSize().padding(paddingValues),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = text)
Button(onClick = viewModel::onButtonClick) {
Text(text = "Click on me")
}
}
}
```
--------------------------------
### Add moko-biometry Dependencies to Kotlin Multiplatform Project
Source: https://context7.com/icerockdev/moko-biometry/llms.txt
Integrates the moko-biometry library into your Kotlin Multiplatform project by adding its dependencies to your Gradle build files. This enables biometric authentication features across Android and iOS. Ensure mavenCentral() is available in your project-level repositories.
```kotlin
// build.gradle.kts (project level)
allprojects {
repositories {
mavenCentral()
}
}
// build.gradle.kts (module level)
kotlin {
sourceSets {
val commonMain by getting {
dependencies {
// Core biometry module
api("dev.icerock.moko:biometry:0.4.0")
// For Compose Multiplatform support
api("dev.icerock.moko:biometry-compose:0.4.0")
}
}
}
}
// For Android-only Jetpack Compose projects
dependencies {
implementation("dev.icerock.moko:biometry-compose:0.4.0")
}
```
--------------------------------
### Android Biometry Integration with Lifecycle Binding
Source: https://context7.com/icerockdev/moko-biometry/llms.txt
On Android, the BiometryAuthenticator requires binding to an Activity's lifecycle and FragmentManager for proper biometric prompt display. This Kotlin code demonstrates creating and binding the authenticator within an AppCompatActivity.
```kotlin
class MainActivity : AppCompatActivity(), AuthViewModel.EventListener {
private lateinit var viewModel: AuthViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val biometryAuthenticator = BiometryAuthenticator(
applicationContext = applicationContext
)
viewModel = getViewModel {
AuthViewModel(biometryAuthenticator = biometryAuthenticator)
}
viewModel.biometryAuthenticator.bind(
lifecycle = this.lifecycle,
fragmentManager = supportFragmentManager
)
}
fun onLoginButtonClick(view: View) {
viewModel.performBiometricLogin()
}
}
```
--------------------------------
### Perform Biometric Authentication using BiometryAuthenticator
Source: https://context7.com/icerockdev/moko-biometry/llms.txt
Initiates a biometric authentication process using the `BiometryAuthenticator`. This suspend function displays a system prompt for fingerprint or face scan. It returns `true` on success, `false` if cancelled, and throws an exception on errors. Utilize this in your shared ViewModel logic.
```kotlin
// commonMain - Shared ViewModel with biometric authentication
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import dev.icerock.moko.biometry.BiometryAuthenticator
import dev.icerock.moko.resources.desc // Assuming 'desc()' is an extension for resource strings
class AuthViewModel(
val biometryAuthenticator: BiometryAuthenticator
) : ViewModel() {
fun performBiometricLogin() = viewModelScope.launch {
try {
val isSuccess = biometryAuthenticator.checkBiometryAuthentication(
requestTitle = "Authenticate".desc(), // Dialog title
requestReason = "Confirm your identity".desc(), // Subtitle/reason
failureButtonText = "Use Password".desc(), // Negative button text
allowDeviceCredentials = false // true = allow PIN/pattern fallback
)
if (isSuccess) {
// Authentication successful - proceed with secure operation
println("Biometric authentication passed")
} else {
// User cancelled or dismissed the prompt
println("Authentication cancelled by user")
}
} catch (exception: Throwable) {
// Authentication failed (too many attempts, biometric not enrolled, etc.)
println("Authentication error: ${exception.message}")
}
}
}
```
--------------------------------
### Check Biometric Availability with BiometryAuthenticator
Source: https://context7.com/icerockdev/moko-biometry/llms.txt
Determines if biometric authentication is available on the current device. This method returns `true` if the hardware supports biometrics and at least one biometric is enrolled, otherwise it returns `false`. Use this to conditionally display biometric login options.
```kotlin
// commonMain - Check biometric availability before showing auth UI
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import dev.icerock.moko.biometry.BiometryAuthenticator
import dev.icerock.moko.resources.desc // Assuming 'desc()' is an extension for resource strings
class SecurityViewModel(
val biometryAuthenticator: BiometryAuthenticator
) : ViewModel() {
fun checkAndAuthenticate() {
if (biometryAuthenticator.isBiometricAvailable()) {
// Biometrics available - show biometric login option
performBiometricLogin()
} else {
// Biometrics not available - fall back to password
showPasswordLoginScreen()
}
}
private fun performBiometricLogin() = viewModelScope.launch {
try {
val success = biometryAuthenticator.checkBiometryAuthentication(
requestTitle = "Biometric Login".desc(),
requestReason = "Authenticate to access your account".desc(),
failureButtonText = "Cancel".desc(),
allowDeviceCredentials = true // Allow device passcode as fallback
)
if (success) onLoginSuccess() else onLoginCancelled()
} catch (e: Throwable) {
onLoginError(e)
}
}
private fun showPasswordLoginScreen() { /* ... */ }
private fun onLoginSuccess() { /* ... */ }
private fun onLoginCancelled() { /* ... */ }
private fun onLoginError(e: Throwable) { /* ... */ }
}
```
--------------------------------
### Bind Biometry Authenticator Effect for Compose Multiplatform
Source: https://context7.com/icerockdev/moko-biometry/llms.txt
A Composable side-effect that binds the BiometryAuthenticator to the current lifecycle. This is crucial for Android to connect the authenticator to the FragmentActivity's lifecycle and FragmentManager. On iOS, it's a no-op but included for cross-platform compatibility. It takes a BiometryAuthenticator instance as input and returns nothing.
```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.unit.dp
import dev.icerock.moko.biometry.BiometryAuthenticator
import dev.icerock.moko.biometry.compose.BindBiometryAuthenticatorEffect
import dev.icerock.moko.biometry.compose.rememberBiometryAuthenticatorFactory
import kotlinx.coroutines.launch
// Dummy extension function for demonstration
fun String.desc(): String = this
sealed class AuthState {
object Idle : AuthState()
object Success : AuthState()
object Cancelled : AuthState()
data class Error(val message: String) : AuthState()
}
@Composable
fun SecureAppScreen() {
val biometryFactory = rememberBiometryAuthenticatorFactory()
val biometryAuthenticator = remember {
biometryFactory.createBiometryAuthenticator()
}
// REQUIRED: Bind to lifecycle for Android compatibility
BindBiometryAuthenticatorEffect(biometryAuthenticator)
var authState by remember { mutableStateOf(AuthState.Idle) }
val scope = rememberCoroutineScope()
Column(
modifier = Modifier.fillMaxSize().padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = when (authState) {
AuthState.Idle -> "Tap to authenticate"
AuthState.Success -> "Authentication successful!"
AuthState.Cancelled -> "Authentication cancelled"
is AuthState.Error -> "Error: ${(authState as AuthState.Error).message}"
}
)
Spacer(modifier = Modifier.height(24.dp))
Button(
onClick = {
scope.launch {
authState = try {
val success = biometryAuthenticator.checkBiometryAuthentication(
requestTitle = "Secure Access".desc(),
requestReason = "Authenticate to continue".desc(),
failureButtonText = "Cancel".desc(),
allowDeviceCredentials = true
)
if (success) AuthState.Success else AuthState.Cancelled
} catch (e: Throwable) {
AuthState.Error(e.message ?: "Unknown error")
}
}
}
) {
Text("Authenticate")
}
}
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.